【发布时间】:2013-01-09 05:33:40
【问题描述】:
仅作为示例,让我们考虑 sun.reflect 包中的类 ClassFileAssembler。
这个类是一个包本地类:
class ClassFileAssembler implements sun.reflect.ClassFileConstants {...
所以我们甚至不能使用它的名字ClassFileAssembler,我们不能直接导入它——这会导致编译器错误。
但是,我们可以在我们的项目中创建一个名为 sun.reflect 的包,并在该包内部使用 ClassFileAssembler 名称 - Java 编译器会认为我们在 ClassFileAssembler 的包中。
如果是这样,为什么不尝试获取对类对象的引用,即ClassFileAssembler.class?
Class<ClassFileAssembler> classFileAssemblerClass = ClassFileAssembler.class;
出乎意料的是,这段代码会导致运行时错误:java.lang.IllegalAccessError: tried to access class sun.reflect.ClassFileAssembler from class sun.reflect.Test。
但是我们仍然能够获得ClassFileAssembler 类对象:
Class<ClassFileAssembler> aClass = (Class<ClassFileAssembler>)Class.forName("sun.reflect.ClassFileAssembler");
它运行良好,并为我们提供了完整的类描述。
所以,问题是:
1) 技术之间有什么区别,Class.forName0 如何检索对类对象的引用,.class 是如何做到的?
2) 为什么他们有如此不同的安全检查?
3) 以这种方式保护.class 引用的原因是什么?
4) 这些技术是否使用不同的类加载器?
【问题讨论】:
-
Class.forName("sun.reflect.ClassFileAssembler")调用该类中的静态初始化程序,如果您将 true 作为第二个参数传递给方法,但不调用构造函数,也不调用 .main 方法。
标签: java reflection class-visibility