Java 8
Funktsional interfeys
Nima bu? Funktsional interfeys - bu bitta bajarilmagan (mavhum) usulni o'z ichiga olgan interfeys. @FunctionalInterface - bunday interfeys ustida joylashgan ixtiyoriy izoh. Funktsional interfeys talablariga javob berishini tekshirish uchun kerak (faqat bitta mavhum usulga ega). Lekin har doimgidek, bizda ba'zi ogohlantirishlar bor: standart va statik usullar bu talablarga kirmaydi. Shuning uchun bunday usullar bir nechta bo'lishi mumkin + bitta mavhum va interfeys funktsional bo'ladi. Shuningdek, u Object sinfining interfeysning funktsional sifatida ta'rifiga ta'sir qilmaydigan usullarini o'z ichiga olishi mumkin. Standart va statik usullar haqida bir necha so'z qo'shaman:-
Standart modifikatorga ega bo'lgan usullar interfeyslarga mavjud ilovalarni buzmasdan yangi usullarni qo'shish imkonini beradi.
public interface Something { default void someMethod { System.out.println("Some text......"); } }
Ha, ha, biz amalga oshirilgan usulni interfeysga qo'shamiz va bu usulni amalga oshirayotganda siz uni bekor qila olmaysiz, lekin uni meros qilib olingan usul sifatida ishlating. Ammo agar sinf berilgan usul bilan ikkita interfeysni amalga oshirsa, bizda kompilyatsiya xatosi bo'ladi va agar u interfeyslarni amalga oshirsa va ma'lum bir o'xshash usulga ega sinfni meros qilib olsa, ota-klass usuli interfeys usullari bilan bir-biriga yopishadi va istisno ishlamaydi.
-
interfeysdagi statik usullar sinfdagi statik usullar bilan bir xil ishlaydi. Unutmang: siz statik usullarni meros qilib olmaysiz, xuddi avlod sinfidan statik usulni chaqira olmaganingizdek.
-
Iste'molchi - T tipidagi argumentni oladi, hech narsa qaytarmaydi (yaroqsiz).
Misol:
void someMethod(T t);
-
Yetkazib beruvchi - kirish sifatida hech narsani qabul qilmaydi, lekin T qiymatini qaytaradi.
Misol:
T someMethod();
-
Funktsiya - kirish sifatida T tipidagi parametrni oladi, R tipidagi qiymatni qaytaradi.
Misol:
R someMethod(T t);
-
UnaryOperator - T argumentini oladi va T tipidagi qiymatni qaytaradi.
Misol:
T someMethod(T t);
Predikat - argument sifatida T qiymatini oladi, mantiqiy qiymatni qaytaradi.
Misol:boolean someMethod(T t);
Oqim
Streams - bu ma'lumotlar tuzilmalarini funktsional uslubda boshqarish usuli. Odatda bu to'plamlar (lekin siz ularni boshqa, kamroq tarqalgan holatlarda ishlatishingiz mumkin). Tushunarliroq tilda aytganda, Stream - bu har birida bo'lgani kabi qo'pol kuch emas, balki bir vaqtning o'zida barcha ma'lumotlar bilan ishlaydigandek ishlov beradigan ma'lumotlar oqimi. Keling, kichik bir misolni ko'rib chiqaylik. Aytaylik, bizda filtrlash (50 dan kam), 5 ga oshirish va qolgan raqamlardan birinchi 4 ta raqamni konsolga chiqarishni istagan raqamlar to'plami bor. Biz buni avvalroq qanday qilgan bo'lardik:List<Integer> list = Arrays.asList(46, 34, 24, 93, 91, 1, 34, 94);
int count = 0;
for (int x : list) {
if (x >= 50) continue;
x += 5;
count++;
if (count > 4) break;
System.out.print(x);
}
Ko'p kod yo'qdek tuyuladi va mantiq allaqachon biroz chalkash. Keling, oqim yordamida qanday ko'rinishini ko'rib chiqaylik:
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)
.filter(x -> x < 50)
.map(x -> x + 5)
.limit(4)
.forEach(System.out::print);
Oqimlar kod miqdorini kamaytirish va uni yanada o'qilishi mumkin qilish orqali hayotni sezilarli darajada soddalashtiradi. Ushbu mavzuni batafsilroq o'rganmoqchi bo'lganlar uchun bu mavzu bo'yicha yaxshi (hatto juda zo'r deb aytaman) maqola .
Lambda
Ehtimol, eng muhim va uzoq kutilgan xususiyat - lambdalarning paydo bo'lishi. Lambda nima? Bu turli joylarga uzatilishi mumkin bo'lgan kod blokidir, shuning uchun uni keyinchalik kerak bo'lganda ko'p marta bajarish mumkin. Juda chalkash tuyuladi, shunday emasmi? Oddiy qilib aytganda, lambdalardan foydalanib, siz funktsional interfeys usulini (anonim sinfni amalga oshirish turini) amalga oshirishingiz mumkin:Runnable runnable = () -> { System.out.println("I'm running !");};
new Thread(runnable).start();
Biz run() usulini tez va keraksiz qog'ozlarsiz amalga oshirdik. Va ha: Runnable - bu funktsional interfeys. Oqimlar bilan ishlashda men ham lambdalardan foydalanaman (yuqoridagi oqimlar misollarida bo'lgani kabi). Biz juda chuqur tushmaymiz, chunki siz juda chuqur sho'ng'ishingiz mumkin, men bir nechta havolalarni qoldiraman, shunda hali ham yuragida qazuvchi bo'lgan yigitlar chuqurroq qazishlari mumkin:
- Habré-da Java 8-dagi lambda ifodalari haqidagi maqola
- Aleksandr Kosarevning blogida Java tilidagi lambda ifodalari haqidagi maqola
har biriga
Java 8-da oqim kabi ma'lumotlar oqimi bilan ishlaydigan yangi fore mavjud. Mana bir misol:List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);
someList.forEach(x -> System.out.println(x));
(someList.stream().foreach(…) ga o'xshash)
Usul ma'lumotnomasi
Yo'naltiruvchi usullar - bu Java sinflari yoki ob'ektlarining mavjud usullari yoki konstruktorlariga :: orqali murojaat qilish uchun mo'ljallangan yangi, foydali sintaksisdir.-
Dizaynerga havola:
SomeObject obj = SomeObject::new
-
Statik usulga havola:
SomeObject::someStaticMethod
-
Muayyan turdagi ob'ektning statik bo'lmagan usuliga havola:
SomeObject::someMethod
-
Muayyan ob'ektning muntazam (statik bo'lmagan) usuliga havola
obj::someMethod
someList.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
Malumot usullari haqida ko'proq ma'lumot olishni istaganlar uchun:
API vaqti
Sanalar va vaqtlar bilan ishlash uchun yangi kutubxona mavjud - java.time. Yangi API har qanday Joda-Time-ga o'xshaydi. Ushbu API ning eng muhim bo'limlari:- LocalDate - aniq sana, misol sifatida - 2010-01-09;
- LocalTime - vaqt mintaqasini hisobga olgan holda vaqt - 19:45:55 (LocalDate ga o'xshash);
- LocalDateTime - kombinatsiyalangan LocalDate + LocalTime - 2020-01-04 15:37:47;
- ZoneId - vaqt zonalarini ifodalaydi;
- Soat - bu turdan foydalanib, joriy vaqt va sanaga kirishingiz mumkin.
- Java va vaqt: Habré-da birinchi va ikkinchi qism
- Java 8 da Date/Time API ga kirish
Ixtiyoriy
Bu java.util to'plamidagi yangi sinf bo'lib , qiymat o'rami bo'lib, uning hiylasi shuki, u xavfsiz tarzda null ni ham o'z ichiga olishi mumkin . Ixtiyoriy qabul qilish: Agar biz Optional.ofOptional<String> someOptional = Optional.of("Something");
da null qiymatini o'tkazsak, biz sevimli NullPointerException ni olamiz . Bunday hollarda ular quyidagilardan foydalanadilar: - bu usulda siz nulldan qo'rqishingiz shart emas. Keyin, dastlab boʻsh boʻlgan ixtiyoriy: boʻsh yoki yoʻqligini tekshirish uchun: “ toʻgʻri” yoki “yolgʻon” qiymatini qaytaradi. Agar qiymat mavjud bo'lsa, ma'lum bir amalni bajaring va qiymat bo'lmasa, hech narsa qilmang: Agar ixtiyoriy bo'sh bo'lsa, o'tkazilgan qiymatni qaytaradigan teskari usul (zaxira rejasi turi): Siz juda va juda uzoq vaqt davom etishingiz mumkin ( Yaxshiyamki, ixtiyoriy ikkala saxiy qo'llar bilan usullarni qo'shdi), lekin biz bu haqda to'xtalmaymiz. Yangi boshlanuvchilar uchun bir nechta havolalarni qoldirganim ma'qul: Optional<String> someOptional = Optional.ofNullable("Something");
Optional<String> someOptional = Optional.empty();
someOptional.isPresent();
someOptional.ifPresent(System.out::println);
System.out.println(someOptional.orElse("Some default content"));
- Java Opsiyonel - holivarlarning otasi
- Majburiy emas: Java 8 da Schrödingerning mushuki
- Java 8 da yangi ixtiyoriy sinf, NullPointerException uchun panacea emas
- Java 8 xususiyatlari: JavaRush uchun yakuniy qo'llanma - Birinchi va Ikkinchi qism ;
- Habré-da Java 8-da yangi ;
- Odamlar haqida gapirmaydigan 10 ta eng yaxshi Java 8 xususiyatlari ;
- Java 8 qo'llanma .
Java 9
Shunday qilib, 2017-yil 21-sentabrda dunyo JDK 9-ni ko‘rdi. Ushbu Java 9 boy funksiyalar to‘plamiga ega. Yangi til tushunchalari mavjud bo'lmasa-da, yangi API va diagnostika buyruqlari albatta ishlab chiquvchilarni qiziqtiradi.JShell (REPL - o'qish-baholash-bosib chiqarish tsikli)
Bu interaktiv konsolning Java dasturi bo'lib, u funksionallikni sinab ko'rish va konsolda interfeyslar, sinflar, enumlar, operatorlar va boshqalar kabi turli konstruksiyalardan foydalanish uchun ishlatiladi. JShellni ishga tushirish uchun terminalda jshell yozish kifoya. Keyin biz tasavvurimiz imkon beradigan narsani yozishimiz mumkin: JShell-dan foydalanib, siz yuqori darajadagi usullarni yaratishingiz va ularni bir seansda ishlatishingiz mumkin. Usullar xuddi statik usullar kabi ishlaydi, faqat statik kalit so'zni o'tkazib yuborish mumkin. Batafsilroq Java 9 REPL (JShell) qo'llanmasida o'qing .Shaxsiy
Java-ning 9-versiyasidan boshlab biz interfeyslarda shaxsiy usullardan foydalanish imkoniyatiga egamiz (standart va statik usullar, chunki biz kirishning etarli emasligi sababli boshqalarni bekor qila olmaymiz).private static void someMethod(){}
try-with-resources
Resurslar bilan sinab ko'rish istisnolarini boshqarish qobiliyati yangilandi:
BufferedReader reader = new BufferedReader(new FileReader("....."));
try (reader2) {
....
}
Modullik ( jigsaw )
Modul - bu yangi modul identifikatori fayli bilan birga tegishli paketlar va resurslar guruhi. Ushbu yondashuv kodning ulanishini bo'shatish uchun ishlatiladi. Bo'shashmasdan ulanish kodning barqarorligi va kengaytirilishi uchun asosiy omil hisoblanadi. Modullik turli darajalarda amalga oshiriladi:- Dasturlash tili.
- Virtual mashina.
- Standart java API.
O'zgarmas to'plam
Java 9 da to'plamni bir qator bilan to'ldirish va uni o'zgarmas qilish imkoniyati paydo bo'ldi (ilgari o'zgarmas to'plam yaratish uchun biz kollektsiya yaratishimiz, uni ma'lumotlar bilan to'ldirishimiz va usulni chaqirishimiz kerak edi, masalan, Collections.unmodifiableList). Bunday yaratilishga misol:List someList = List.of("first","second","third");
Boshqa innovatsiyalar:
- kengaytirilgan Majburiy emas (yangi usullar qo'shilgan);
- operatsion tizimning harakatlarini boshqarish uchun ProcessHandle va ProcessHandle interfeyslari paydo bo'ldi;
- G1 - standart axlat yig'uvchi;
- HTTP/2 protokollari va WebSocket-ni qo'llab-quvvatlaydigan HTTP mijozi;
- kengaytirilgan oqim;
- qo'shilgan Reactive Streams API ramkasi (reaktiv dasturlash uchun);
- Habré-da Java 9-ni ko'rib chiqish
- Java 9. Nima yangiliklar?
- Java 9: Yangi xususiyatlar
- Java 9 - Siz hali yangiladingizmi? Yo'qmi? Va bu kerak emas ...!?
- Sander Mak Java modullariga o'tish haqida
Java 10
Shunday qilib, Java 9 chiqarilganidan olti oy o'tgach, 2018 yil mart oyida (men buni kechagidek eslayman), Java 10 sahnaga chiqdi.var
Endi biz ma'lumotlar turini taqdim etishimiz shart emas. Biz xabarni var sifatida belgilaymiz va kompilyator o'ng tomonda mavjud bo'lgan initsializator turiga qarab xabar turini aniqlaydi. Bu xususiyat faqat initsializatorga ega mahalliy o'zgaruvchilar uchun mavjud: uni usul argumentlari, qaytarish turlari va boshqalar uchun ishlatib bo'lmaydi, chunki turni aniqlash uchun boshlang'ich mavjud emas. Misol var (String turi uchun):var message = "Some message…..";
System.out.println(message);
var kalit so'z emas: u aslida int kabi ajratilgan turdagi nomdir . Varning foydasi katta: turdagi deklaratsiyalar hech qanday foyda keltirmasdan katta e'tiborni oladi va bu xususiyat vaqtni tejaydi. Ammo shu bilan birga, agar o'zgaruvchi uzoq usullar zanjiridan olingan bo'lsa, kod kamroq o'qilishi mumkin bo'ladi, chunki u erda qanday ob'ekt mavjudligi darhol noma'lum. Ushbu funksiya bilan ko'proq tanishishni istaganlar uchun mo'ljallangan:
- Java 10 LocalVariable Type-Inference
- Java 10 da "var" bilan birinchi aloqa
- 26 Java-da var Type-dan foydalanish bo'yicha maslahatlar
JIT kompilyatori (GraalVM)
Yana bir bor eslatib o'tmoqchimanki, javac buyrug'ini ishga tushirganingizda Java ilovasi Java kodidan JVM baytkodiga kompilyatsiya qilinadi, bu ilovaning ikkilik ko'rinishidir. Ammo oddiy kompyuter protsessori JVM bayt kodini oddiygina bajara olmaydi. JVM dasturingiz ishlashi uchun protsessor allaqachon foydalanishi mumkin bo'lgan mashina kodiga aylantirilgan ushbu bayt-kod uchun boshqa kompilyator kerak. Javac bilan solishtirganda, bu kompilyator ancha murakkab, lekin ayni paytda yuqori sifatli mashina kodini ishlab chiqaradi. Hozirgi vaqtda OpenJDK HotSpot virtual mashinasini o'z ichiga oladi, u o'z navbatida ikkita asosiy JIT kompilyatoriga ega. Birinchisi, C1 ( mijoz kompilyatori ) yuqori tezlikda ishlash uchun mo'ljallangan, ammo kodni optimallashtirish zarar ko'radi. Ikkinchisi C2 (server kompilyatori). Amalga oshirish tezligi yomonlashadi, lekin kod yanada optimallashtirilgan. Qaysi biri qachon ishlatiladi? C1 uzoq JIT pauzalarini istamaydigan ish stoli ilovalari uchun, C2 esa kompilyatsiyaga ko'proq vaqt sarflashga chidash mumkin bo'lgan uzoq muddatli server dasturlari uchun juda mos keladi. Ko'p darajali kompilyatsiya - bu kompilyatsiya birinchi marta C1 orqali o'tadi va natija C2 orqali o'tadi (kattaroq optimallashtirish uchun ishlatiladi). GraalVM - bu HotSpotni to'liq almashtirish uchun yaratilgan loyiha. Biz Graalni bir nechta tegishli loyihalar sifatida tasavvur qilishimiz mumkin: HotSpot uchun yangi JIT kompilyatori va yangi poliglot virtual mashinasi. Ushbu JIT kompilyatorining o'ziga xosligi shundaki, u Java tilida yozilgan. Graal kompilyatorining afzalligi - bu xavfsizlik, ya'ni buzilishlar emas, balki istisnolar, xotiraning oqishi emas. Shuningdek, bizda yaxshi IDE yordami bo'ladi va biz tuzatuvchilar, profilerlar yoki boshqa qulay vositalardan foydalana olamiz. Bundan tashqari, kompilyator HotSpot-dan mustaqil bo'lishi mumkin va u o'zining tezroq JIT kompilyatsiya qilingan versiyasini yaratishi mumkin. Qazuvchilar uchun:- Yangi Java JIT kompilyatoriga chuqur kirib boring
- Graal: Haqiqiy hayotda yangi JVM JIT kompilyatoridan qanday foydalanish kerak
- Graal qanday ishlaydi - Java JVM JIT kompilyatori
Parallel G1
G1 axlat yig'uvchisi, albatta, ajoyib, bunga shubha yo'q, lekin u ham zaif nuqtaga ega: u bir tishli to'liq GC tsiklini bajaradi. Foydalanilmayotgan ob'ektlarni topish uchun sizga barcha jihozlar kerak bo'lganda, biz bitta ip bilan cheklanamiz. Java 10 buni tuzatdi.Endi GC biz unga qo'shgan barcha resurslar bilan ishlaydi (ya'ni u ko'p tarmoqli bo'ladi). Bunga erishish uchun til ishlab chiquvchilari GC dan asosiy manbalarning izolyatsiyasini yaxshiladilar va GC uchun chiroyli toza interfeys yaratdilar. Ushbu yoqimlilikni ishlab chiquvchilari, OpenJDK, nafaqat yangi GC-larni yaratishni iloji boricha soddalashtirish, balki yig'ilishdan keraksiz GC-larni tezda o'chirib qo'yish uchun koddagi axlatni tozalashlari kerak edi. Muvaffaqiyatning asosiy mezonlaridan biri bu barcha yaxshilanishlardan keyin ish tezligida pasayishning yo'qligi. Keling, shuningdek, qaraylik: Boshqa innovatsiyalar:- Toza axlat yig'uvchi interfeysi joriy etildi. Bu turli xil axlat yig'uvchilardan manba kodining izolyatsiyasini yaxshilaydi, bu muqobil kollektorlarni tez va og'riqsiz birlashtirish imkonini beradi;
- JDK manbalarini bitta omborga birlashtirish;
- To'plamlar yangi usulni oldi - copyOf (Collection) , bu to'plamning o'zgarmas nusxasini qaytaradi;
- Ixtiyoriy (va uning variantlari) yangi usulga ega .orElseThrow() ;
- Bundan buyon JVM'lar Docker konteynerida ishlayotganligini bilishadi va operatsion tizimning o'ziga so'rov o'tkazishdan ko'ra konteynerga xos konfiguratsiyani olishadi.
- Java 10 uchun qo'llanma
- 10 JDK 10 xususiyatlari Java ishlab chiquvchilari bilishi kerak
- Java 10-dagi yangiliklar: Birinchi va Ikkinchi qism
GO TO FULL VERSION