Only for example lets consider the class ClassFileAssembler
from the sun.reflect
package.
This class is a package local class:
class ClassFileAssembler implements sun.reflect.ClassFileConstants {...
So we can not use even its name ClassFileAssembler
, we can not import it directly - it will lead to a compiler error.
However we can create a package named sun.reflect
in our project and use the ClassFileAssembler
name internally in this package - Java compiler will think that we are inside the ClassFileAssembler
's package.
If so, why not to try to get a reference to a class object, i.e. ClassFileAssembler.class
?
Class<ClassFileAssembler> classFileAssemblerClass = ClassFileAssembler.class;
Unexpectedly this code leads to a run-time error: java.lang.IllegalAccessError: tried to access class sun.reflect.ClassFileAssembler from class sun.reflect.Test
.
However we still able to get the ClassFileAssembler
class object:
Class<ClassFileAssembler> aClass = (Class<ClassFileAssembler>)Class.forName("sun.reflect.ClassFileAssembler");
It works fine and gives us a full class description.
So, the questions are:
1) What is the difference between techniques, how Class.forName0
retrieves reference to class object, and how .class
does it?
2) Why do they have such different security checks?
3) What's the reason to protect .class
reference in such way?
4) Do these techniques use different class loaders?
If you check the javadoc of Class#forName
, you will see that:
Note that this method does not check whether the requested class is accessible to its caller.