在静态方法(注释为@CallerSensitive
)中,我尝试获取调用类的名称:
@CallerSensitive
public static void someMethod() {
String name = sun.reflect.Reflection.getCallerClass().getName();
...
}
我收到错误:
java.lang.InternalError: CallerSensitive annotation expected at frame 1
这里有什么问题?
参考
更新
我正在使用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_STATIC, ACC_NATIVE
Deprecated: true
Signature: #81 // (I)Ljava/lang/Class<*>;
RuntimeVisibleAnnotations:
0: #82()
答案 0 :(得分:12)
只有特权代码才能使用此批注。 如果代码是通过bootstrap类加载器或扩展类加载器加载的,则代码具有特权。
摘自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();
答案 1 :(得分:0)
getCallerClass()
。当我在Java 8中运行此示例时,我得到相同的错误。使用Java 7(1.7.0_55)运行我得到了调用类的名称。无论如何,我会避免直接从太阳使用任何东西。*包层次结构。
要获取调用类的名称,您可以执行以下操作(我只使用实例初始化程序获取名称,您应该从SecurityManager派生并在类中提供getCallerClass()方法):
public static void someMethod() {
new SecurityManager() {
{
String name = getClassContext()[1].getSimpleName();
System.err.println(name == null ? "null" : name);
}
};
}