Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat
Post #317
4.22K
JA @java_fillthegaps
Showing posts older than #318 · Back to latest
String str = "a" + "b";Будет две части:
stream().filter(x -> x<3)В байткоде на месте вызова лямбды появляется инструкция
invokedynamic #2, 0Следуем по указателям из Constant Pool и попадаем в секцию бутстрап-методов. Видим там вызов
LambdaMetafactory.metafactory(…)
Этот фабричный метод возвращает объект CallSite, внутри которого спрятался MethodHandle. class Smth$$Lambda$14/0x0000000800c02460Класс динамический и существует только в памяти.
Predicate p = i -> x<3;То ожидается, что p - это объект. Его можно куда-то передать и вызвать его методы.
invokedynamic #7, 02️⃣ В пуле констант находим такую запись
#7 = InvokeDynamic #0:#83️⃣ Идём по ссылкам и попадаем в специальную секцию .class файла под названием BootstrapMethods.
javap -c -v UserInfo.classПри первом использовании файл с байткодом загружается с диска и регистрируется внутри JVM. Нам интересны четыре сущности:
#14=Utf8 Autumn2️⃣ Список байткод инструкций
#16=Class #18
#17=NameAndType #19:#20
29: getstatic #39Все конкретные методы и аргументы обозначаются через ссылки из Constant Pool.
32: aload_3
33: invokevirtual #45
Lookup pl = MethodHandles.publicLookup();2️⃣ Задаём сигнатуру метода
MethodType mt = MethodType.methodType(String.class, Integer.class, Long.class);Первый аргумент (String.class) - это возвращаемое значение, остальные - входные параметры.
MethodHandle mh = all.findVirtual(User.class, "findName", mt);Это ссылка на метод findName в классе User, который принимает на вход два параметра и возвращает String.
String res = mh.invoke(1, 2L);Выбор методов на каждом этапе гораздо шире, но разбирать мы их, конечно, не будем.
LoggerFactory.getLogger(AccountService.class);Эта строка копируется из класса в класс, меняется только имя в скобках. Операция настолько простая, что можно забыть это сделать🙂
Logger.getLogger(MethodHandles.lookup().lookupClass());то можно спокойно копировать строчку и ничего не менять.
fun(s: Integer): boolean { return s<3; }
Легко для понимания, сложно для реализации. Java - ООП язык, всё в JVM заточено под работу объектов и примитивов. Добавить новый тип данных - чудовищно огромная работа. Как функция будет хранится, вызываться и взаимодействовать с другими объектами? Будет ли она работать с дженериками? Тысячи вопросов и сложностей.Predicate p = i -> i<3;Выглядит по-джавовски и отлично впишется в текущую систему. Существующие библиотеки будут работать с лямбдами по умолчанию.
public boolean lambda(Integer i) { return i<3; }
MethodHandle mh = LDC["lambda"];
И подставляем mh в исходный код:...stream().filter(mh)...В теории решение отличное, на практике - неподходящее.
Function<Integer,Integer> sum = (a,b) → a+b;В чём преимущество лямбда-выражений?
Iterator it=list.iterator();Метод next возвращает текущий элемент и сдвигает указатель на следующий. Метод hasNext проверяет, ссылается ли этот указатель куда-нибудь. Этот паттерн повторяется снова и снова и называется Iteration.
while(it.hasNext())
int result = it.next();