2016-10-26 3 views
3

JDK8 преобразовать лямбда-выражения для анонимного класса вКак переопределить лямбда анонимный класс в Java

InnerClassLambdaMetafactory.spinInnerClass() { 
    return UNSAFE.defineAnonymousClass(targetClass, classBytes, null); 
} 

Я пишу javaagent, использовать ассемблер для изменения classBytes (добавить метод) и передать его в defineAnonymousClass, но этот метод заканчивается классом ClassNotFoundException этого анонимного класса. есть ли способ изменить содержание анонимных classBytes?

ответ

0

Преобразование анонимно загруженных классов является сложным. Вы обновляете уже загруженные классы, которые представляют такие классы? Если да, то обратите внимание, что Class::getName не возвращает фактическое двоичное имя класса, но добавляет случайный хеш, такой как my.DefinedType/12345, где вам нужно будет снять последние числа.

Кроме того, вы не можете ссылаться на такие классы непосредственно из другого класса, но вам нужно ссылаться на них непосредственно из API отражения или в идеале дескриптора метода. Вы не можете искать такие классы из загрузчика классов, поэтому их называют анонимными.

Наконец, при установке файлового трансформатора класса загрузка таких анонимных классов не регистрируется в трансформаторе. Самый простой способ справиться с такими классами - это исправить lambda meta factory, который отвечает за создание типов лямбда. Вы можете сделать это легко с помощью, например Byte Buddy, который позволяет создать агента:

new AgentBuilder.Default() 
    .with(LambdaTransformationStrategy.ENABLED) 
    .type(someMatcher) 
    .transform(someTransformer) 
    .installOn(instrumentation); 

Вызов этого, под одеялом, Byte Buddy переписывает лямбда по умолчанию мета класс фабрики в JVM и заменяет его своим собственным кодогенерации где такая аппаратура возможна.

+0

Другие классы могут ссылаться на анонимный класс напрямую, если они также являются анонимными классами и имеют исправленный постоянный пул (это третий параметр 'defineAnonymousClass'). В этом случае это также не имеет значения, какое имя они используют. – Holger

+0

Это верно. Но это не относится к классам, описывающим лямбда-выражения. –

+0

Благодарим вас за ответ, я не пытаюсь ретранслировать уже загруженный класс, но просто модифицирую байты анонимного класса до его создания. все еще не знаю, почему он не работает. как определить анонимный класс с помощью 'targetClass.getClassLoader.defineClass (modifiededAnonymousClassBytes)'? есть ли какая-нибудь сторона? – nzomkxia