我想创建一个方法来接受T实现任何接口的任何类I。
然后对类做一些事情并返回实现的接口I。
这是我尝试过的:
class MyLibrary {
public static <I, T extends I> I registerImplementation(Class<T> classImpl) {
I interfaceImpl = (I) classImpl.newInstance();
return interfaceImpl;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建一个接口和一个实现该接口的类:
interface UserInterface {
void doSomethingDefined();
}
class UserClass_v1_10_R2 implements UserInterface {
@Override
public void doSomethingDefined() {
System.out.println("What this does is well-defined");
}
public void doVersionSpecificStuff() {
System.out.println("This is not in the interface, so don't really depend on this");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我调用方法引用时UserClass,它返回相同的类类型T而不是接口类型I,从而允许调用所有未在接口中声明的类方法。
即在下面的语句中,即使 …
我正在使用带有实例引用的自定义View类作为编辑器.视图仅用于片段.我需要实例引用,所以我总是可以获得自定义View的自定义参数.
public static StoryView instance;
private Story story;
public static Story getCurrentStory(){
if(instance == null) return null;
else return instance.story;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用此getter方法更改Navigation Drawer的内容时,我收到一条警告:
在这里:
private static IDrawerItem[] drawerEditorItems(){
Story s = StoryView.getCurrentStory();
SectionDrawerItem section_editor = new SectionDrawerItem()
.withName(str("placeholder_story_by", s.name, s.author))
.withDivider(false);
return new IDrawerItem[]{ section_editor };
}
Run Code Online (Sandbox Code Playgroud)
str(String id, Object... args) 是一种静态方法,基本上格式化i18n字符串.
我的猜测是,在s函数范围的末尾可能通过赋值来销毁引用s = null?也许这可能会破坏instance.story我的自定义View中的实际内容?
在随机#nextLong()文档指出此方法不会返回所有可能的long值:
从此随机数生成器的序列返回下一个伪随机、均匀分布的 long 值。的一般约定nextLong是伪随机生成并返回一个 long 值。该方法nextLong由 Random 类实现,就像通过:
public long nextLong() {
return ((long) next(32) << 32) + next(32);
}
Run Code Online (Sandbox Code Playgroud)
因为 Random 类使用只有 48 位的种子,所以该算法不会返回所有可能的长值。
例如,数字8090327796378429294是可生成的,但数字8090327796378429295不是,即使它们唯一的区别是一个最低有效位,并且值本身是 63 位长。
有一种方法可以通过nextLong()使用以下算法来知道是否可以返回值:
public class JavaRandom {
private static final long ADD = 0xBL;
private static final long MULT = 0x5DEECE66DL;
private static final long TWO16 = 1L << 16;
private static final long MASK_31 = (1L << …Run Code Online (Sandbox Code Playgroud) 我正在使用 Java 代理 (Agent.class) 以包含对 Agent 类的调用的方式转换程序 (Program.class) 中的方法。
public Program.getMultiplier()F:
ALOAD 1
ALOAD 2
FDIV
+ INVOKESTATIC Agent.getCustomMultiplier(F)F
FRETURN
Run Code Online (Sandbox Code Playgroud)
我检查了代理类和程序类的类加载器及其父类,它们的层次结构如下所示:
AppClassLoader<- PlatformClassLoader<-nullURLClassLoader<- PlatformClassLoader<-null当程序执行添加的INVOKESTATIC指令时,它会抛出 ClassNotFoundException - 它无法找到 Agent 类,因为它是由不同的类加载器加载的。
作为临时解决方案,我尝试强制AppClassLoader成为URLClassLoaderwith 反射的父级,它适用于较旧的 Java 版本,但自 Java 12 以来已被删除。
有没有更可靠的方法来确保我的代理类在任何类加载器中都是可见的?
我想从 Java 动态调用本机方法。因为方法签名在编译时是未知的,所以我为大多数具有相同签名的原始返回类型创建了通用本机方法:
class NativeHook {
public static native int callInt(String funcName, Object... funcArgs);
public static native void callVoid(String funcName, Object... funcArgs);
public static native Object callObject(String funcName, Object... funcArgs);
private static MethodHandle getNativeMethod(String callName, Class<?> returnType) {
return MethodHandles.lookup().findStatic(NativeHook.class, callName,
MethodType.methodType(returnType, String.class, Object[].class));
}
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找创建一个 MethodHandle ,然后调用匹配的callXXX方法并传入装箱的方法,funcArgs就好像它们是单独提供的一样。这些callXXX方法可以这样访问:
MethodHandle callInt = getNativeMethod("callInt", int.class);
MethodHandle boundCallInt = callInt.bindTo("my_c_function_name").asVarargsCollector(Object[].class);
// returns NativeHook.callInt("my_c_function_name", 1, 2, 3)
boundCallInt.invokeWithArguments(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
我正在使用这个 bootstrap 方法callXXX在 invokeDynamic 中间接引用这个方法,它的工作方式与上面相同: …
java ×5
jvm ×2
android ×1
bytecode ×1
classloader ×1
generics ×1
javaagents ×1
random ×1
random-seed ×1