据我所知,构造函数,实例初始化器和静态初始化器只是具有特殊名称的方法。我知道<
和>
是普通标识符的非法字符。
如何将这些特殊方法检索为Method
个对象(或类似的东西)并调用他们?你可以看看我写的这段代码片段:
public class Program {
/**
* static <init>() {
* }
*/
static {
}
/**
* <init>() {
* }
*/
{
}
/**
* <cinit>() {
* }
*/
Program(){
}
public static void main(String[] args) throws ReflectiveOperationException {
//get native getDeclaredMethods method
Method Class$getDeclaredMethods0 = Class.class.getDeclaredMethod("getDeclaredMethods0", boolean.class);
Class$getDeclaredMethods0.setAccessible(true);
//list methods of this class
Method[] methods = (Method[])Class$getDeclaredMethods0.invoke(Program.class, false);
for (Method m : methods) {
System.out.println(m);
}
//Console output:
/*
public static void dirty.Program.main(java.lang.String[]) throws java.lang.ReflectiveOperationException
*/
}
}
答案 0 :(得分:0)
你做不到。您可以为声明的构造函数获取Constructor
个实例,但是没有Java类型表示可调用的静态或实例初始化程序。
答案 1 :(得分:0)
你不能使用静态初始化程序。对于实例初始化程序,它们由构造函数执行,如果没有关联的构造函数执行它们就没有意义(它们要求实例存在)。
从Java 7和java.lang.invoke开始,您可以将MethodHandle
用于构造函数。您将以与常规方法相同的方式调用它们。例如,这是我用于构建异常实例的代码的提取(注意:Java 8):
private static final Lookup LOOKUP
= MethodHandles.publicLookup();
// Method type for a constructor accepting a Throwable as an argument
private static final MethodType TYPE
= MethodType.methodType(void.class, Throwable.class);
private MethodHandle getHandle(final Class<? extends RuntimeException> c)
{
return handles.computeIfAbsent(c, key -> {
try {
return LOOKUP.findConstructor(c, TYPE)
.asType(TYPE.changeReturnType(RuntimeException.class));
} catch (IllegalAccessException | NoSuchMethodException e) {
throw new InstantiationException(e);
}
});
}
@SuppressWarnings("unchecked")
public <E extends RuntimeException> E get(final Class<E> c,
final Throwable t)
{
try {
return (E) getHandle(c).invokeExact(t);
} catch (InstantiationException e) {
e.addSuppressed(t);
throw e;
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable oops) {
final RuntimeException exception = new InstantiationException(oops);
exception.addSuppressed(t);
throw exception;
}
}