Java 8
Функционалдык интерфейс
Бул эмне? Функционалдык интерфейс – бул бир аткарылбаган (абстрактуу) методду камтыган интерфейс. @FunctionalInterface мындай интерфейстин үстүнө жайгаштырылган кошумча annotation. Функционалдык интерфейстин талаптарына жооп берерин текшерүү үчүн керек (бир гана абстракттуу ыкмасы бар). Бирок, адаттагыдай эле, бизде кээ бир эскертүүлөр бар: демейки жана статикалык методдор бул талаптарга төп келбейт. Ошондуктан, мындай ыкмалар бир нече болушу мүмкүн + бир абстракттуу, жана интерфейс функционалдуу болот. Ал ошондой эле функционалдык интерфейстин аныктамасына таасирин тийгизбеген Object классынын ыкмаларын камтышы мүмкүн. Мен демейки жана статикалык ыкмалар жөнүндө бир нече сөздү кошом:-
Демейки модификатору бар методдор интерфейстерге жаңы методдорду кошууга мүмкүндүк берет, алардын учурдагы аткарылышын бузбастан.
public interface Something { default void someMethod { System.out.println("Some text......"); } }
Ооба, ооба, биз ишке ашырылган ыкманы интерфейске кошобуз жана бул ыкманы ишке ашырууда сиз аны жокко чыгара албайсыз, бирок аны мурас катары колдонуңуз. Бирок эгер класс берилген метод менен эки интерфейсти ишке ашырса, анда бизде компиляция катасы пайда болот жана ал интерфейстерди ишке ашырып, классты белгилүү окшош метод менен мурастап алса, ата-эне класстын ыкмасы интерфейстин ыкмаларын кайталайт жана өзгөчө кырдаал иштебейт.
-
Интерфейстеги статикалык методдор класстагы статикалык методдордой эле иштейт. Унутпаңыз: статикалык методдорду тукум куума класстан чакыра албагандай эле, сиз статикалык ыкмаларды мурастай албайсыз.
-
Керектөөчү - T түрүндөгү аргументти алат, эч нерсе кайтарbyte (жараксыз).
Мисал:
void someMethod(T t);
-
Жабдуучу - киргизүү катары эч нерсени кабыл алbyte, бирок T маанисин кайтарат.
Мисал:
T someMethod();
-
Функция - киргизүү катары T түрүндөгү параметрди алат, R түрүндөгү маанини кайтарат.
Мисал:
R someMethod(T t);
-
UnaryOperator - T аргументин алат жана T түрүндөгү маанини кайтарат.
Мисал:
T someMethod(T t);
Предикат - аргумент катары кандайдыр бир T маанисин алат, логикалык маанини кайтарат.
Мисал:boolean someMethod(T t);
Агым
Агымдар функционалдык стилде маалымат структураларын иштетүүнүн бир жолу. Эреже катары, бул жыйнактар (бирок сиз аларды башка, азыраак таралган учурларда колдоно аласыз). Түшүнүктүү тил менен айтканда, Stream – бул ар бири үчүн колдонулгандай катаал күч эмес, бир эле учурда бардык маалыматтар менен иштегендей иштеткен маалымат агымы. Келгиле, кичинекей бир мисалды карап көрөлү. Бизде чыпкалоону каалаган (50дөн аз) сандар топтому бар дейли, 5ке көбөйтүп, калгандарынан биринчи 4 санды консолго чыгарабыз. Муну мурда кантип кылмакпыз: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);
}
Код көп эмес окшойт жана логика бир аз баш аламан. Келгиле, агым менен ал кандай болорун карап көрөлү:
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)
.filter(x -> x < 50)
.map(x -> x + 5)
.limit(4)
.forEach(System.out::print);
Агымдар codeдун көлөмүн азайтуу жана аны окууга ыңгайлуу кылуу менен жашоону абдан жөнөкөйлөтөт. Бул теманы кененирээк изилдегиси келгендер үчүн, бул тема боюнча жакшы (жакшы деп айтаар элем) макала .
Ламбда
Балким, эң маанилүү жана көптөн күткөн өзгөчөлүк - бул ламбдалардын пайда болушу. lambda деген эмне? Бул codeдун блогу, аны ар кайсы жерлерге өткөрүүгө болот, андыктан аны кийинчерээк керек болсо көп жолу аткарууга болот. Абдан түшүнүксүз угулат, туурабы? Жөнөкөй сөз менен айтканда, ламбдаларды колдонуу менен, сиз функционалдык интерфейстин ыкмасын (анонимдүү классты ишке ашыруунун бир түрү) ишке ашыра аласыз:Runnable runnable = () -> { System.out.println("I'm running !");};
new Thread(runnable).start();
Биз run() ыкмасын тез жана керексиз бюрократиясыз ишке ашырдык. Жана ооба: Runnable - бул функционалдык интерфейс. Мен агымдар менен иштегенде ламбдаларды да колдоном (жогоруда агым менен мисалдардагыдай). Биз өтө тереңге барбайбыз, анткени биз бир топ тереңдей алабыз, мен дагы эле жүрөгүн казуучу балдар тереңирээк казышы үчүн бир нече шилтеме калтырам:
- Habré боюнча Java 8 лямбда туюнтмалары жөнүндө макала
- Александр Косаревдин блогунда Java тorндеги ламбда туюнтмалары жөнүндө макала
ар бирине
Java 8де жаңы foreach бар, ал агым сыяктуу маалымат агымы менен иштейт. Бул жерде бир мисал:List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);
someList.forEach(x -> System.out.println(x));
(someList.stream().foreach(...)га окшош)
Метод шилтемеси
Шилтеме методдору - бул Java класстарынын же an objectтеринин учурдагы ыкмаларына же конструкторлоруна шилтеме жасоо үчүн иштелип чыккан жаңы, пайдалуу синтаксис :: Метод шилтемелери төрт түргө бөлүнөт:-
Дизайнерге шилтеме:
SomeObject obj = SomeObject::new
-
Статикалык ыкма шилтемеси:
SomeObject::someStaticMethod
-
Белгилүү бир типтеги an objectтин статикалык эмес ыкмасына шилтеме:
SomeObject::someMethod
-
Белгилүү бир an objectтин кадимки (статикалык эмес) ыкмасына шилтеме
obj::someMethod
someList.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
Шилтеме ыкмалары жөнүндө көбүрөөк маалымат алууну каалагандар үчүн:
API убакыты
Даталар жана убакыттар менен иштөө үчүн жаңы китепкана бар - java.time. Жаңы API ар кандай Joda-Time окшош. Бул API эң маанилүү бөлүмдөрү:- LocalDate - белгилүү бир дата, мисалы - 2010-01-09;
- LocalTime - убакыт алкагын эске алуу менен убакыт - 19:45:55 (LocalDate аналогу);
- LocalDateTime - айкалыштырылган LocalDate + LocalTime - 2020-01-04 15:37:47;
- ZoneId - убакыт алHowтарын билдирет;
- Саат - бул түрүн колдонуу менен учурдагы убакыт жана датага кире аласыз.
- Java жана убакыт: Habré боюнча биринчи жана экинчи бөлүк
- Java 8деги Date/Time API'ге киришүү
Кошумча
Бул java.util топтомундагы жаңы класс , баалуулук орогуч, анын амалы нөлдү да камтышы мүмкүн . Кошумча кабыл алуу: Эгерде Optional.ofOptional<String> someOptional = Optional.of("Something");
ичинде null өтсө , биз сүйүктүү NullPointerException алабыз . Мындай учурларда алар төмөнкүлөрдү колдонушат: - бул ыкмада нөлдөн коркпошуңуз керек. Андан кийин, башында бош түзүңүз Кошумча: Анын бош экенин текшерүү үчүн: бизге чындыкты же жалганды кайтарып берет. Мааниси бар болсо, белгилүү бир аракетти аткарыңыз, ал эми маани жок болсо эч нерсе кылбаңыз: Кошумча бош болсо, өткөн маанини кайтаруучу тескери ыкма (резервдик пландын түрү): Сиз абдан, өтө узак убакытка уланта аласыз ( бактыга жараша, Кошумча эки берешен колдору менен ыкмаларды кошту), бирок биз бул жөнүндө токтолбойбуз. Баштоочулар үчүн бир нече шилтеме калтырганым жакшы: 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 Optional - holivars атасы
- Кошумча: Java 8деги Schrödinger's Cat
- Java 8деги жаңы Кошумча класс, NullPointerException үчүн панацея эмес
- Java 8 өзгөчөлүктөрү: JavaRush үчүн акыркы колдонмо - Биринчи жана Экинчи бөлүк ;
- Habré боюнча Java 8де жаңы ;
- Адамдар айтпай турган 10 Java 8 өзгөчөлүктөрү ;
- Java 8 окуу куралы .
Java 9
Ошентип, 2017-жылдын 21-сентябрында дүйнө JDK 9ду көрдү. Бул Java 9 көптөгөн мүмкүнчүлүктөргө ээ. Жаңы тил түшүнүктөрү жок болсо да, жаңы API'лер жана диагностикалык буйруктар иштеп чыгуучуларды кызыктырат.JShell (REPL - окуу-баалоо-басып чыгаруу цикли)
Бул интерфейстер, класстар, энумдар, операторлор ж.б. сыяктуу функцияларды текшерүү жана консолдо ар кандай конструкцияларды колдонуу үчүн колдонулган интерактивдүү консолдун Java ишке ашыруусу. JShellди ишке киргизүү үчүн терминалга jshell жазуу керек. Ошондо биз фантазиябыз кандай болсо ошону жаза алабыз: JShell аркылуу сиз жогорку деңгээлдеги ыкмаларды түзүп, аларды ошол эле сессиянын ичинде колдоно аласыз. Методдор статикалык методдор сыяктуу иштейт, бирок статикалык ачкыч сөздү калтырып коюуга болот.Көбүрөөк Java 9 REPL (JShell) колдонмосунан окуңуз .Жеке
Java versionсынын 9-versionсынан баштап, интерфейстерде жеке ыкмаларды колдонуу мүмкүнчүлүгүбүз бар (демейки жана статикалык ыкмалар, анткени биз жөн гана жеткorктүүлүктүн жетишсиздигинен башкаларды жокко чыгара албайбыз).private static void someMethod(){}
try-with-resources
"Ресурстар менен аракет кылуу" өзгөчөлүктөрүн иштетүү жөндөмү өркүндөтүлдү:
BufferedReader reader = new BufferedReader(new FileReader("....."));
try (reader2) {
....
}
Модулярдуулук ( Jigsaw )
Модуль - бул жаңы модулдун дескриптор файлы менен байланышкан пакеттердин жана ресурстардын тобу. Бул ыкма codeдун байланышын бошотуу үчүн колдонулат. Бошоң туташтыруу codeдун туруктуулугу жана кеңейтилүүсү үчүн негизги фактор болуп саналат. Модулдуулук ар кандай деңгээлде ишке ашырылат:- Программалоо тor.
- Виртуалдык машина.
- Стандарттык java API.
Immutable Collection
Java 9да коллекцияны бир сап менен түзүүгө жана толтурууга мүмкүн болуп калды, ошол эле учурда аны өзгөрүлгүс кылып (мурда өзгөрүлгүс коллекцияны түзүү үчүн коллекция түзүп, аны маалыматтар менен толтуруп, методду чакырышыбыз керек болчу, мисалы, Collections.unmodifiableList). Мындай жаратуунун мисалы:List someList = List.of("first","second","third");
Башка инновациялар:
- кеңейтилген Кошумча (жаңы ыкмалар кошулган);
- иштетүү тутумунун аракеттерин көзөмөлдөө үчүн ProcessHandle жана ProcessHandle интерфейстери пайда болду;
- G1 - демейки таштанды жыйноочу;
- HTTP/2 протоколдорун жана WebSocketти колдогон HTTP кардары;
- кеңейтилген агым;
- кошулган Reactive Streams API алкагы (реактивдүү программалоо үчүн);
- Habré боюнча Java 9ду карап чыгуу
- Java 9. Эмне жаңылык?
- Java 9: Жаңы мүмкүнчүлүктөр
- Java 9 - Сиз жаңырттыңызбы? Жок? Анан кереги жок...!?
- Сандер Мак Java модулдарына өтүү боюнча
Java 10
Ошентип, Java 9 чыккандан алты ай өткөндөн кийин, 2018-жылдын март айында (мен кечээгидей эсимде), Java 10 сахнага чыкты.var
Эми биз маалымат түрүн беришибиз керек эмес. Биз кабарды var деп белгилейбиз жана компилятор кабардын түрүн оң жактагы инициализатордун түрү боюнча аныктайт. Бул функция инициализатору бар локалдык өзгөрмөлөр үчүн гана жеткorктүү: аны метод аргументтери, кайтаруу түрлөрү ж.б. үчүн колдонууга болбойт, анткени түрүн аныктоо үчүн инициализатор жок. Мисал var (Стринг түрү үчүн):var message = "Some message…..";
System.out.println(message);
var ачкыч сөз эмес: ал негизинен int сыяктуу сакталган типтин аталышы . Var'дын пайдасы чоң: типтеги декларациялар эч кандай пайда алып келбестен көп көңүл бурат жана бул функция убакытты үнөмдөйт. Бирок, ошол эле учурда, эгер өзгөрмө ыкмалардын узун тизмегинен алынса, code азыраак окула баштайт, анткени ал жерде кандай an object жатканы дароо түшүнүксүз. Бул функция менен көбүрөөк таанышууну каалагандарга арналган:
- Java 10 LocalVariable Type-Inference
- Java 10до "var" менен биринчи байланыш
- 26 Java тorнде var Type колдонуу боюнча кеңештер
JIT компилятору (GraalVM)
Андан ары созбостон, javac буйругун иштеткенде, Java тиркемеси Java codeунан JVM byte codeуна түзүлөөрүн эсиңизге сала кетейин, бул тиркеменин бинардык өкүлчүлүгү болуп саналат. Бирок кадимки компьютер процессору JVM byte codeун жөн эле аткара алbyte. JVM программаңыз иштеши үчүн сизге бул byte code үчүн башка компилятор керек, ал процессор мурунтан эле колдоно алган машина codeуна айландырылат. Javac менен салыштырганда, бул компилятор алда канча татаал, бирок ошондой эле жогорку сапаттагы машина codeун чыгарат. Учурда OpenJDK HotSpot виртуалдык машинасын камтыйт, ал өз кезегинде эки негизги JIT компиляторуна ээ. Биринчиси, C1 ( кардар компилятору ), жогорку ылдамдыкта иштөө үчүн иштелип чыккан, бирок codeду оптималдаштыруу жабыркайт. Экинчиси C2 (server компилятору). Аткаруу ылдамдыгы азаят, бирок code көбүрөөк оптималдаштырылган. Кайсысы качан колдонулат? C1 узак JIT тыныгуусу жагымсыз болгон десктоп тиркемелери үчүн эң сонун, ал эми C2 компиляцияга көбүрөөк убакыт сарптоого мүмкүн болгон узакка созулган serverдик программалар үчүн сонун. Көп деңгээлдүү компиляция биринчи жолу компиляция C1 аркылуу өтүп, натыйжа C2 аркылуу өтөт (чоңураак оптималдаштыруу үчүн колдонулат). GraalVM толугу менен HotSpot алмаштыруу үчүн түзүлгөн долбоор болуп саналат. Биз Граалды бир нече окшош долбоорлор деп эсептесек болот: HotSpot үчүн жаңы JIT компилятору жана жаңы полиглоттук виртуалдык машина. Бул JIT компиляторунун өзгөчөлүгү анын Java тorнде жазылганында. Graal компиляторунун артыкчылыгы - коопсуздук, башкача айтканда, каталар эмес, бирок эс тутумдун агып кетиши эмес. Бизде ошондой эле жакшы IDE колдоосу болот жана биз мүчүлүштүктөрдү оңдоочуларды, профилдерди же башка ыңгайлуу куралдарды колдоно алабыз. Кошумчалай кетсек, компилятор HotSpot'тан көз карандысыз болушу мүмкүн жана ал өзүнүн тезирээк JIT-компиляцияланган versionсын түзө алат. казуучулар үчүн:- Жаңы Java JIT компиляторуна терең сүңгүңүз
- Graal: Жаңы JVM JIT компиляторун чыныгы жашоодо кантип колдонсо болот
- Graal кантип иштейт - Java JVM JIT компилятору
Параллель G1
G1 таштанды жыйноочу, албетте, сонун, бул жөнүндө эч кандай шек жок, бирок анын алсыз жери да бар: ал бир жиптүү толук GC циклин аткарат. Колдонулбаган an objectилерди табуу үчүн сиз чогулта турган аппараттык каражаттардын бардык күчү керек болгон учурда, биз бир жип менен чектелебиз. Java 10 муну оңдоду. Эми GC биз ага кошкон бардык ресурстар менен иштейт (башкача айтканда, ал көп жиптүү болуп калат). Буга жетишүү үчүн тилди иштеп чыгуучулар GC үчүн жакшы таза интерфейсти түзүп, негизги булактарды GCден изоляциялоону жакшыртышты. Бул сүйкүмдүүлүктүн иштеп чыгуучулары, OpenJDK, жаңы GC түзүүнү мүмкүн болушунча жөнөкөйлөштүрүү үчүн гана эмес, ошондой эле керексиз GCлерди чогулуштан тез өчүрүүгө мүмкүндүк берүү үчүн codeдогу таштандыны атайын тазалоо керек болчу. Ийгorктин негизги критерийлеринин бири - бул бардык жакшыртуулардан кийин иштөө ылдамдыгынын төмөндөшүнүн жоктугу. Ошондой эле карап көрөлү: Башка инновациялар:- Таза таштанды жыйноочу интерфейси киргизилди. Бул ар кандай таштанды жыйноочулардан баштапкы codeдун изоляциясын жакшыртат, бул альтернативдик коллекторлорду тез жана оорутпай бириктирүүгө мүмкүндүк берет;
- JDK булактарын бир репозиторийге бириктирүү;
- Коллекциялар жаңы ыкманы алышты - copyOf (Collection) , бул коллекциянын өзгөрүлбөс көчүрмөсүн кайтарат;
- Кошумча (жана анын варианттарында) .orElseThrow() жаңы ыкмасы бар ;
- Мындан ары, JVMs алар Docker контейнеринде иштеп жатканын бorшет жана операциялык системанын өзүнө суроо салбастан, контейнерге тиешелүү конфигурацияны алышат.
- Java 10 колдонмосу
- 10 JDK 10 өзгөчөлүктөрү Java иштеп чыгуучулар бorши керек
- Java 10догу жаңылыктар: Биринчи жана Экинчи бөлүк
GO TO FULL VERSION