在静态方法(使用@CallerSensitive注释)中,我尝试获取调用类的名称:
@CallerSensitive public static void someMethod() { String name = sun.reflect.Reflection.getCallerClass().getName(); ... }
我收到错误:
java.lang.InternalError: CallerSensitive annotation expected at frame 1
这有什么不对?
参考
> http://www.infoq.com/news/2013/07/Oracle-Removes-getCallerClass
> http://openjdk.java.net/jeps/176
UPDATE
我正在使用java 8(u25)并且不推荐使用方法getCallerClass()(不推荐使用getCallerClass(int)),这可以在反汇编字节码时看到:
$/usr/lib/jvm/java-8-oracle/bin/javap -cp /usr/lib/jvm/java-8-oracle/jre/lib/rt.jar -verbose sun.reflect.Reflection > bytecode
Classfile jar:file:/usr/lib/jvm/jdk1.8.0_25/jre/lib/rt.jar!/sun/reflect/Reflection.class Last modified Sep 17,2014; size 6476 bytes Compiled from "Reflection.java" public class sun.reflect.Reflection minor version: 0 major version: 52 flags: ACC_PUBLIC,ACC_SUPER Constant pool: #78 = Utf8 Lsun/reflect/CallerSensitive; #80 = Utf8 Deprecated #82 = Utf8 Ljava/lang/Deprecated; { public sun.reflect.Reflection(); descriptor: ()V flags: ACC_PUBLIC public static native java.lang.Class<?> getCallerClass(); descriptor: ()Ljava/lang/Class; flags: ACC_PUBLIC,ACC_STATIC,ACC_NATIVE Signature: #76 // ()Ljava/lang/Class<*>; RuntimeVisibleAnnotations: 0: #78() public static native java.lang.Class<?> getCallerClass(int); descriptor: (I)Ljava/lang/Class; flags: ACC_PUBLIC,ACC_NATIVE Deprecated: true Signature: #81 // (I)Ljava/lang/Class<*>; RuntimeVisibleAnnotations: 0: #82()
解决方法
只有特权代码才能使用此批注.
如果代码是通过引导类加载器或扩展类加载器加载的,则代码具有特权.
如果代码是通过引导类加载器或扩展类加载器加载的,则代码具有特权.
摘自Open JDK源文件classFileParser.cpp
// Privileged code can use all annotations. Other code silently drops some. const bool privileged = loader_data->is_the_null_class_loader_data() || loader_data->is_ext_class_loader_data() || loader_data->is_anonymous();