A class mentioned in field or method descriptor is not checked for accessibility by the VM. Nor must the named class be visible to the mentioning class's class loader [1], or even to any class loader at all [2].
However, the design of java.lang.invoke requires all MethodTypes to be encoded with Class objects, which necessitates loading appropriate classes; the resolution of CONSTANT_MethodType structures in class files (JVMS 5.4.3.5) further requires an accessibility check.
This means that certain perfectly valid invocations, declarations, etc., cannot be successfully described abstractly using MethodTypes and MethodHandles. E.g., were a class file to be preprocessed, replacing all its invokestatic instructions with "equivalent" invokedynamic instructions, new errors could occur, as the VM attempted to resolve classes that, in the original bytecode, would be left unresolved.
To address this limitation, I suggest exploring the possibility of enhancing MethodType to represent its component types as Strings as an alternative to Classes. That may be a rather deep change, but as is the feature can't live up to its promise of equivalence with concrete bytecode. (Expressiveness aside, it's also a potential performance problem to require every mentioned class to be loaded immediately.)
As a followup, resolution of CONSTANT_MethodType (JVMS 5.4.3.5) could then be modified to avoid loading any classes.
-----
[1] Class loader constraints ensure that two class loaders agree on the meaning of a name in a declaration/use or overrider/overridee scenario -- but *only if* both class loaders attempt to load a class with that name. If one of them never loads such a class, the constraint cannot be violated.
----
[2] Example of a class name that goes completely unresolved:
Source file: ResolutionTest.java:
-
public class ResolutionTest {
public static void main(String... args) {
System.out.println(C.f);
System.out.println(C.m());
}
}
class C {
static Missing f;
static Missing m() { return null; }
}
class Missing {}
-
javac ResolutionTest.java
rm Missing.class
java ResolutionTest
Output:
null
null
(In practice, this kind of thing might arise if the classes for an optional feature of some system are sometimes unavailable.)