Иконка ресурса

Прекрасный мир байт-кода

1,111
47
420
JustAGod добавил(а) новый ресурс:

Прекрасный мир байт-кода - зарубаемся в байт-код(жестко)

Предисловие
Етак, добрый вечер. Данная статья преследует цель в общих чертах дать вам широкое представление о том как работать с байт-кодом JVM при помощи библиотеки ASM.
Эта статья не является гайдом для новичков, для понимания того что тут происходит вам нужно написать хотя бы один простейший трансформер.

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

Узнать больше об этом ресурсе...
 
7,099
324
1,510
Я как то раз решил, что справедливо будет утверждать, что java/lang/Object является родителем для всех и просто переопределил ClassWriter#getCommonSuperClass так чтоб он всегда возвращал java/lang/Object.
Так вот хочу предостеречь таких же мечтателей. Так нельзя поверьте на слово. Слишком долго объяснять почему. Просто попробуйте потом теренарные операторы с аперкастом.
Я правильно понимаю, что это что-то вроде наибольшего общего делителя, но для "алгебры" классов?
~~~
INVOKEDYNAMIC
Oracle решили генерировать лямбды в рантайме
Параметры тут будут только если лямбда захватила какую то переменную в себя
А это как-то улучшает ситуацию с тем, что замыкания по идее нужно создавать каждый раз? Или это вообще не связано?
Например, есть два кода:
Java:
Map<String, String> map = ...;

void someMethod(String key){
    String value =
        map.computeIfAbsent(key, key1->key1+"test"); //создавать лямбду можно один раз, она не зависит от аргументов someMethod
}
Java:
void someMethod2(String key, String addend){
    String value =
        map.computeIfAbsent(key, key1->key1+addend); //создавать лямбду требуется при каждом вызове someMethod, она зависит от его аргументов
}
 
Последнее редактирование:
1,111
47
420
Ну если мы будем считать интерфейсы и родителей множителями, то да.
Можно пойти дальше и сказать, что Object это единица, а классы без родителя и интерфейсов - это простые числа.
Но как по мне это не нужная метафора. Просто этот метод вернет общего родителя. Например для Exception и List вернется Object. Для Long и Integer вернется Number. That’s it.
 
7,099
324
1,510
Ближайшего общего родителя, единица ведь не подходит
~~~
Там добавил еще вопрос...
 
1,111
47
420
Я правильно понимаю, что это что-то вроде наибольшего общего делителя, но для "алгебры" классов?
~~~

А это как-то улучшает ситуацию с тем, что замыкания по идее нужно создавать каждый раз? Или это вообще не связано?
Например, есть два кода:
Java:
Map<String, String> map = ...;

void someMethod(String key){
    String value =
        map.computeIfAbsent(key, key1->key1+"test"); //создавать лямбду можно один раз, она не зависит от аргументов someMethod
}
Java:
void someMethod2(String key, String addend){
    String value =
        map.computeIfAbsent(key, key1->key1+addend); //создавать лямбду требуется при каждом вызове someMethod, она зависит от его аргументов
}
ну фани лямбды замыканиями называть конечно, но я немного не понял вопроса. Лямбду как класс создать нужно один раз а вот новый инстанс очевидно каждый раз да
 
7,099
324
1,510
Так единица это Object, и в статье сказано, что это выстрел в ногу, а не решение
 
1,111
47
420
Дело в том что она подходит но не всегда
Например есть у нас два метода
Java:
List<Int> a();

Set<Int> b();

И мы пишем
Java:
Collection<Int> c() {
    return expression() ? a() : b();
}

Вот примерно в этот момент нам нужно в байт-коде узнать общего родителя.
Загляним в байт-код

Код:
call expression
je else
call a
goto end
label: else
call b
label: end

areturn

Примерно на опкоде areturn мы будем создавать стэк мапу, в которой скажем жаве какой тип лежит на стеке.
ASM на этом моменте вызовет getCommonSuperClass от List<Int> и Set<Int>. Если мы вернем Object, ASM так и запишет, и тогда JVM в рантайме выскажет нам, что мы пытаемся вернуть Object когда ожидается Collection. That's it.
 
Сверху