Groovy 如何能够访问 Java class 的私有方法?
How is Groovy able to access private methods of a Java class?
Groovy可以访问Javaclass的私有方法和变量。 Groovy 是如何在幕后做到这一点的?是不是因为invokedynamic
字节码指令被MethodHandle
class使用了?我认为 Java 使用 invokespecial
指令调用 private
方法,使用 invokevirtual
调用 public
正确的访问修饰符?
你可以在 Java 中使用反射来完成这个,例如,这个方法将设置一个私有静态字段的值...
public static void setStaticField(Class<?> clazz, String fieldName, Object value) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
} catch (Exception ex) {
throw new IllegalArgumentException("Could not set field '" + fieldName + "' of type '" + clazz.getName() + "' to: " + value, ex);
}
}
通知field.setAccessible(true)
这可以通过设置适当的安全管理器策略来防止。参见 How to restrict developers to use reflection to access private methods and constructors in Java?
Groovy是写在Java里的,所以希望不要直接依赖字节码,不是用Reflection API.
有关更多详细信息,请查看源代码中的 java.lang.reflect
,然后您将看到它如何在幕后使用反射 API。
你可以使用java.lang.reflect
import java.lang.reflect.Method
// ....
Method method = a.getClass().getDeclaredMethod('initializeSeoCode')
method.setAccessible(true)
java.lang.Object r = method.invoke(a)
Groovy可以访问Javaclass的私有方法和变量。 Groovy 是如何在幕后做到这一点的?是不是因为invokedynamic
字节码指令被MethodHandle
class使用了?我认为 Java 使用 invokespecial
指令调用 private
方法,使用 invokevirtual
调用 public
正确的访问修饰符?
你可以在 Java 中使用反射来完成这个,例如,这个方法将设置一个私有静态字段的值...
public static void setStaticField(Class<?> clazz, String fieldName, Object value) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
} catch (Exception ex) {
throw new IllegalArgumentException("Could not set field '" + fieldName + "' of type '" + clazz.getName() + "' to: " + value, ex);
}
}
通知field.setAccessible(true)
这可以通过设置适当的安全管理器策略来防止。参见 How to restrict developers to use reflection to access private methods and constructors in Java?
Groovy是写在Java里的,所以希望不要直接依赖字节码,不是用Reflection API.
有关更多详细信息,请查看源代码中的 java.lang.reflect
,然后您将看到它如何在幕后使用反射 API。
你可以使用java.lang.reflect
import java.lang.reflect.Method
// ....
Method method = a.getClass().getDeclaredMethod('initializeSeoCode')
method.setAccessible(true)
java.lang.Object r = method.invoke(a)