Классы, созданные с помощью MethodHandles.Lookup.defineClass
, регистрируются в загрузчике определяющих классов, как и любой другой класс, и на них можно ссылаться по именам, как и обычные классы.Они могут даже заменить статически скомпилированные классы при регистрации до того, как эти классы будут разрешены, как в следующем примере:
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
public class LookupDynamicClass {
public static void main(String[] args) throws IllegalAccessException {
MethodHandles.Lookup lookup = MethodHandles.lookup();
lookup.defineClass(("Êþº¾\0\0\0005\0\26\11\0\11\0\12\10\0\13\12\0\14\0"
+"\15\7\0\16\7\0\17\1\0\3foo\1\0\3()V\1\0\4Code\7\0\20\14\0\21\0\22\1\0"
+"\30hello from dynamic class\7\0\23\14\0\24\0\25\1\0\4Lazy\1\0\20java/"
+"lang/Object\1\0\20java/lang/System\1\0\3out\1\0\25Ljava/io/PrintStream;"
+"\1\0\23java/io/PrintStream\1\0\7println\1\0\25(Ljava/lang/String;)V\6\0"
+"\0\4\0\5\0\0\0\0\0\1\0\11\0\6\0\7\0\1\0\10\0\0\0\25\0\2\0\0\0\0\0\11²\0"
+ "\1\22\2¶\0\3±\0\0\0\0\0\0").getBytes(StandardCharsets.ISO_8859_1));
Lazy.foo();
}
}
interface Lazy {
static void foo() {
}
}
Попробуйте это онлайн
Этот пример динамическиопределяет класс Lazy
, метод foo()
которого будет вызывать hello from dynamic class
при вызове.
На JVM, таких как HotSpot, где символическая ссылка "Lazy
" разрешается лениво, то есть прямо при попыткеinvoke Lazy.foo()
сделан, это закончится в динамически определенном классе.Для JVM, которые с готовностью разрешают символьные ссылки, класс Lazy
уже существует, когда вызывается MethodHandles.Lookup.defineClass
, и поэтому будет выдано LinkageError
с сообщением типа «попытка повторного определения для Lazy».
Inдругими словами, эти динамически сгенерированные классы имеют то же пространство имен (контекст загрузки классов), что и статически скомпилированные классы.Будучи зарегистрированными в загрузчике классов как обычный класс, они могут собирать мусор только тогда, когда загрузчик определяющего класса становится недоступным (включая все его определенные классы), как в случае с обычными классами.