我正在尝试从每个扩展parse(CharSequence, DateTimeFormatter)
类的类中反映TemporalAccessor
方法。
private static final Map<Class<?>, MethodHandle> PARSE_HANDLES = synchronizedMap(new HashMap<>());
static <T extends TemporalAccessor> MethodHandle parseMethodHandle(final Class<T> clazz) {
if (clazz == null) {
throw new NullPointerException("clazz is null");
}
return PARSE_HANDLES.computeIfAbsent(clazz, k -> {
try {
final Method method = clazz.getMethod("parse", CharSequence.class, DateTimeFormatter.class);
log.debug("method: {}, {}", method, method.isAccessible());
// i don't understand; public static method is not accessible? yet it isn't.
assert method.isAccessible(); // NOT GOOD with UTs
return MethodHandles.lookup().unreflect(method);
} catch (final ReflectiveOperationException roe) {
throw new RuntimeException(roe);
}
});
}
通过YearMonth
类,我明白了。
method: public static java.time.YearMonth java.time.YearMonth.parse(java.lang.CharSequence,java.time.format.DateTimeFormatter), false
为什么无法访问public static
方法?
答案 0 :(得分:4)
请参见the documentation for isAccessible
:
不建议使用此方法,因为它的名称暗示它实际上指示是否禁止检查Java语言访问控制时,检查反射对象是否可访问。 此方法可能会在调用者可访问的反射对象上返回
false
。要测试此反射对象是否可访问,应使用canAccess(Object)
。
(我的重点。)
答案 1 :(得分:1)
使用Java Reflection API,您可以通过设置 accessible 标志来覆盖方法的可访问性。可以由method.setAccessible(true)
执行。
现在isAccessible()
方法并没有您所想的那样,它只是检查标准Java访问检查当前是否被覆盖。
这意味着,如果标准访问修饰符允许,您当然可以使用反射调用该方法。否则,您必须设置 accessible 标志。