JavaRush /Java блогы /Random-KK /8-ден 13-ке дейін: Java нұсқаларына толық шолу. 1 бөлім
Константин
Деңгей

8-ден 13-ке дейін: Java нұсқаларына толық шолу. 1 бөлім

Топта жарияланған
Котята, барлығына сәлем)) Сонымен, бүгін біз 2020 жылымыз, Java 14 шығарылымына өте аз уақыт қалды. Дайын нұсқаны 17 наурызда күтуіңіз керек, біз сол жерде ненің жаңа және қызықты екенін талдаймыз, бірақ бүгін Java-ның алдыңғы нұсқаларында жадымды жаңартқым келеді. Олар бізге қандай жаңалық әкелді? Қарап көрейік. Шолуды Java 8-ден бастайық, өйткені ол әлі де өзекті және көптеген жобаларда қолданылады. 8-ден 13-ке дейін: Java нұсқаларына толық шолу.  1 - 1 бөлімБұрын жаңа нұсқалар әр 3-5 жыл сайын шығарылатын, бірақ жақында Oracle басқа тәсілді қолданды - «әр жарты жыл сайын жаңа Java». Осылайша, әр алты ай сайын біз мүмкіндіктердің шығарылуын көреміз. Жақсы ма, жаман ба, оны әркім әрқалай көреді. Мысалы, маған бұл онша ұнамайды, өйткені жаңа нұсқаларда көптеген жаңа мүмкіндіктер жоқ, бірақ сонымен бірге нұсқалар жаңбырдан кейінгі саңырауқұлақтар сияқты өсіп келеді. Мен Java 8-мен жобада бірнеше рет жыпылықтадым, және Java 16 шығарылды (бірақ ол сирек шыққанда, жаңа мүмкіндіктер жиналады және соңында бұл оқиға мереке сияқты көптен күтіледі: барлығы талқылап жатыр. жаңа тәттілер және сіз оның жанынан өте алмайсыз). Ендеше, бастайық!

Java 8

Функционалдық интерфейс

Бұл не? Функционалдық интерфейс – бір орындалмаған (абстрактілі) әдісті қамтитын интерфейс. @FunctionalInterface - мұндай интерфейстің үстінде орналасқан қосымша annotation. Функционалдық интерфейс талаптарына сәйкес келетінін тексеру үшін қажет (тек бір дерексіз әдіс бар). Бірақ әдеттегідей, бізде кейбір ескертулер бар: әдепкі және статикалық әдістер бұл талаптарға сәйкес келмейді. Сондықтан мұндай бірнеше әдістер болуы мүмкін + бір дерексіз, ал интерфейс функционалды болады. Ол сонымен қатар функционалдық интерфейстің анықтамасына әсер етпейтін Object класының әдістерін қамтуы мүмкін. Мен әдепкі және статикалық әдістер туралы бірнеше сөз қосамын:
  1. Әдепкі модификаторы бар әдістер интерфейстерге олардың бар іске асырылуын бұзбай жаңа әдістерді қосуға мүмкіндік береді.

    public interface Something {
      default void someMethod {
          System.out.println("Some text......");
      }
    }

    Иә, иә, біз интерфейске енгізілген әдісті қосамыз және бұл әдісті жүзеге асырған кезде оны қайта анықтауға болмайды, бірақ оны мұра ретінде пайдаланыңыз. Бірақ егер класс берілген әдіспен екі интерфейсті жүзеге асырса, бізде компиляция қатесі болады, ал егер ол интерфейстерді жүзеге асырса және белгілі бір ұқсас әдіспен классты мұраға алса, ата-аналық класс әдісі интерфейс әдістерімен қабаттасады және ерекшелік жұмыс істемейді.

  2. интерфейстегі статикалық әдістер сыныптағы статикалық әдістермен бірдей жұмыс істейді. Ұмытпаңыз: сіз статикалық әдістерді мұраға ала алмайсыз, сол сияқты сіз статикалық әдісті ұрпақ класынан шақыра алмайсыз.

Сонымен, функционалдық интерфейстер туралы тағы бірнеше сөз және әрі қарай жүрейік. Міне, FI негізгі тізімдері (қалғандары олардың сорттары):

    Предикат – аргумент ретінде кейбір T мәнін қабылдайды, логикалық мәнді қайтарады.

    Мысалы:boolean someMethod(T t);

  • Тұтынушы – T түріндегі аргумент қабылдайды, ештеңені қайтармайды (жарамсыз).

    Мысалы:void someMethod(T t);

  • Жабдықтаушы - кіріс ретінде ештеңе қабылдамайды, бірақ кейбір T мәнін қайтарады.

    Мысалы:T someMethod();

  • Функция – кіріс ретінде T типті параметрді қабылдайды, R түрінің мәнін береді.

    Мысалы:R someMethod(T t);

  • UnaryOperator – T аргументін қабылдайды және T түріндегі мәнді қайтарады.

    Мысалы:T 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 көлемін азайту және оны оқуға ыңғайлы ету арқылы өмірді айтарлықтай жеңілдетеді. Осы тақырыпты толығырақ зерттегісі келетіндер үшін осы тақырып бойынша жақсы (тіпті тамаша дер едім) мақала .

Ламбда

Мүмкін, ең маңызды және көптен күткен қасиет - ламбдалардың пайда болуы. Ламбда дегеніміз не? Бұл әртүрлі орындарға берілуі мүмкін code блогы, сондықтан оны кейінірек қажет болғанша бірнеше рет орындауға болады. Өте түсініксіз естіледі, солай емес пе? Қарапайым сөзбен айтқанда, ламбдаларды пайдалана отырып, сіз функционалды интерфейс әдісін (анонимді классты жүзеге асыру түрі) жүзеге асыра аласыз:
Runnable runnable = () -> { System.out.println("I'm running !");};

new Thread(runnable).start();
Біз run() әдісін тез және қажетсіз бюрократиясыз енгіздік. Иә: Runnable - бұл функционалды интерфейс. Мен ағындармен жұмыс істегенде ламбдаларды да қолданамын (жоғарыдағы ағындардағы мысалдардағыдай). Біз тым тереңге бармаймыз, өйткені біз өте терең сүңгуіміз мүмкін, мен әлі де жүрегінде қазбалар бар жігіттер тереңірек қазып алуы үшін бірнеше сілтеме қалдырамын:

әрқайсысы үшін

Java 8-де ағын сияқты деректер ағынымен жұмыс істейтін жаңа foree бар. Міне, мысал:
List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);

someList.forEach(x -> System.out.println(x));
(someList.stream().foreach(…) аналогы)

Әдіс анықтамасы

Анықтамалық әдістер — Java сыныптарының немесе нысандарының бар әдістеріне немесе конструкторларына :: арқылы сілтеме жасауға арналған жаңа, пайдалы синтаксис.
  1. Дизайнерге сілтеме:

    SomeObject obj = SomeObject::new

  2. Статикалық әдіс сілтемесі:

    SomeObject::someStaticMethod

  3. Белгілі бір типтегі an objectінің статикалық емес әдісіне сілтеме:

    SomeObject::someMethod

  4. Белгілі бір an objectінің тұрақты (статикалық емес) әдісіне сілтеме

    obj::someMethod

Көбінесе әдіс сілтемелері ламбдалардың орнына ағындарда қолданылады (анықтамалық әдістер ламбдаларға қарағанда жылдамырақ, бірақ оқылудан төмен).
someList.stream()

        .map(String::toUpperCase)

      .forEach(System.out::println);
Анықтамалық әдістер туралы қосымша ақпарат алғысы келетіндер үшін:

API уақыты

Күндер мен уақыттармен жұмыс істеуге арналған жаңа кітапхана пайда болды - java.time. 8-ден 13-ке дейін: Java нұсқаларына толық шолу.  1-2 бөлімЖаңа API кез келген Joda-Time-ге ұқсас. Бұл API ең маңызды бөлімдері:
  • LocalDate – нақты күн, мысал ретінде – 2010-01-09;
  • LocalTime - уақыт белдеуін есепке алатын уақыт - 19:45:55 (LocalDate аналогы);
  • LocalDateTime - құрама LocalDate + LocalTime - 2020-01-04 15:37:47;
  • ZoneId – уақыт белдеулерін көрсетеді;
  • Сағат - осы түрді пайдалану арқылы ағымдағы уақыт пен күнге қол жеткізуге болады.
Міне, осы тақырып бойынша бірнеше қызықты мақалалар:

Қосымша

Бұл 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 8-дегі ең танымал инновацияларды қарастырдық - бұл бәрі емес. Егер сіз көбірек білгіңіз келсе, мен сізге мынаны қалдырдым:

Java 9

Осылайша, 2017 жылдың 21 қыркүйегінде әлем JDK 9-ды көрді. Бұл Java 9 мүмкіндіктерінің мол жиынтығымен келеді. Жаңа тіл тұжырымдамалары болмаса да, жаңа API интерфейстері мен диагностикалық пәрмендер әзірлеушілерді қызықтыратыны сөзсіз. 8-ден 13-ке дейін: Java нұсқаларына толық шолу.  1-4 бөлім

JShell (REPL - оқу-бағалау-басып шығару циклі)

Бұл функционалдылықты тексеру және консольдегі интерфейстер, сыныптар, нөмірлер, операторлар және т.б. сияқты әртүрлі құрылымдарды пайдалану үшін пайдаланылатын интерактивті консольдің Java іске асыруы. JShell іске қосу үшін терминалға jshell жазу керек. Содан кейін біз қиялымызға мүмкіндік беретін нәрсені жаза аламыз: 8-ден 13-ке дейін: Java нұсқаларына толық шолу.  1 - 5 бөлімJShell көмегімен сіз жоғары деңгейлі әдістерді жасай аласыз және оларды бір сеанс ішінде пайдалана аласыз. Әдістер статикалық әдістер сияқты жұмыс істейді, тек статикалық кілт сөзді өткізіп жіберуге болады Толығырақ Java 9 REPL (JShell) нұсқаулығында оқыңыз .

Жеке

Java-ның 9-нұсқасынан бастап бізде интерфейстерде жеке әдістерді пайдалану мүмкіндігі бар (әдепкі және статикалық әдістер, өйткені біз қол жеткізудің жеткіліксіздігінен басқаларды жай ғана анықтай алмаймыз). private static void someMethod(){} try-with-resources «Ресурстармен әрекет ету» ерекше жағдайларын өңдеу мүмкіндігі жаңартылды:
BufferedReader reader = new BufferedReader(new FileReader("....."));
  try (reader2) {
  ....
}

Модульдік ( Джигсо )

Модуль – жаңа модуль дескриптор файлымен бірге байланысты пакеттер мен ресурстар тобы. Бұл тәсіл codeтың байланысын босату үшін қолданылады. Бос ілінісу codeты сақтау және кеңейту үшін негізгі фактор болып табылады. Модульдік әртүрлі деңгейлерде жүзеге асырылады:
  1. Бағдарламалау тілі.
  2. Виртуалды машина.
  3. Стандартты java API.
JDK 9 92 модульмен келеді: біз оларды пайдалана аламыз немесе өзімізді жасай аламыз. Мұнда тереңірек қарау үшін бірнеше сілтеме берілген:

Өзгермейтін жинақ

Java 9-да коллекцияны өзгермейтін етіп жасай отырып, бір жолмен құру және толтыру мүмкін болды (бұрын өзгермейтін коллекция жасау үшін коллекция құру, оны деректермен толтыру және әдісті шақыру қажет болды, мысалы, Collections.unmodifiableList). Мұндай туындының мысалы: List someList = List.of("first","second","third");

Басқа инновациялар:

  • кеңейтілген Қосымша (жаңа әдістер қосылды);
  • операциялық жүйенің әрекеттерін басқару үшін ProcessHandle және ProcessHandle интерфейстері пайда болды;
  • G1 – әдепкі қоқыс жинағыш;
  • HTTP/2 протоколдары мен WebSocket протоколдарына қолдау көрсететін HTTP клиенті;
  • кеңейтілген ағын;
  • қосылған Reactive Streams API құрылымы (реактивті бағдарламалау үшін);
Java 9-ға толық ену үшін мен сізге оқуға кеңес беремін:

Java 10

Осылайша, Java 9 шығарылғаннан кейін алты ай өткен соң, 2018 жылдың наурыз айында (мен кешегідей есімде), Java 10 сахнаға шықты. 8-ден 13-ке дейін: Java нұсқаларына толық шолу.  1-6 бөлім

var

Енді бізге деректер түрін берудің қажеті жоқ. Хабарламаны var деп белгілейміз және компилятор хабарламаның түрін оң жақтағы инициализатордың түрі бойынша анықтайды. Бұл мүмкіндік тек инициализаторы бар жергілікті айнымалылар үшін қол жетімді: оны әдіс аргументтері, қайтару түрлері және т.б. үшін пайдалану мүмкін емес, себебі түрін анықтай алатын инициализатор жоқ. Var мысалы (String түрі үшін):
var message = "Some message…..";
System.out.println(message);
var кілт сөз емес: ол негізінен int сияқты сақталған түр атауы . Var- тың пайдасы зор: типтік мәлімдемелер ешқандай пайда әкелместен көп көңіл бөледі және бұл мүмкіндік уақытты үнемдейді. Бірақ сонымен бірге, егер айнымалы әдістердің ұзақ тізбегінен алынса, code аз оқылатын болады, өйткені ол жерде қандай нысан жатқаны бірден түсініксіз. Бұл функциямен көбірек танысқысы келетіндерге арналған:

JIT компиляторы (GraalVM)

Көп ұзамай, javac пәрменін іске қосқан кезде Java қолданбасы Java codeынан қолданбаның екілік көрінісі болып табылатын JVM byte codeына жинақталатынын еске салайын. Бірақ қарапайым компьютерлік процессор JVM byte codeын жай ғана орындай алмайды. JVM бағдарламаңыздың жұмыс істеуі үшін сізге осы byte codeқа арналған басқа компилятор қажет, ол процессор пайдалана алатын машиналық codeқа түрлендіріледі. Javac-пен салыстырғанда бұл компилятор әлдеқайда күрделі, бірақ сонымен бірге жоғары сапалы машина codeын шығарады. Қазіргі уақытта OpenJDK HotSpot виртуалды машинасын қамтиды, ол өз кезегінде екі негізгі JIT компиляторына ие. Біріншісі, C1 ( клиент компиляторы ) жоғары жылдамдықпен жұмыс істеуге арналған, бірақ codeты оңтайландыру зардап шегеді. Екіншісі - C2 (server құрастырушы). Орындау жылдамдығы төмендейді, бірақ code оңтайландырылған. Қайсысы қашан қолданылады? C1 ұзақ JIT үзілістері қажет емес жұмыс үстелі қолданбалары үшін тамаша, ал C2 компиляцияға көбірек уақыт жұмсауға болатын ұзақ жұмыс істейтін serverлік бағдарламалар үшін тамаша. Көпдеңгейлі компиляция - бұл жинақ алдымен C1 арқылы, ал нәтиже C2 арқылы өтеді (үлкен оңтайландыру үшін пайдаланылады). GraalVM - бұл HotSpot-ты толығымен ауыстыру үшін жасалған жоба. Біз Graal-ті бірнеше байланысты жобалар ретінде қарастыруға болады: HotSpot үшін жаңа JIT компиляторы және жаңа полиглоттық виртуалды машина. Бұл JIT компиляторының ерекшелігі оның Java тілінде жазылғанында. Graal компиляторының артықшылығы - қауіпсіздік, яғни апаттар емес, жадтың ағып кетуі емес, ерекше жағдайлар. Бізде жақсы IDE қолдауы болады және біз отладчиктерді, профильдерді немесе басқа ыңғайлы құралдарды пайдалана аламыз. Сонымен қатар, компилятор HotSpot-тан тәуелсіз болуы мүмкін және ол өзінің жылдамырақ JIT құрастырылған нұсқасын жасай алады. Жер қазушылар үшін:

Параллель G1

G1 қоқыс жинағышы, әрине, керемет, бұл туралы күмән жоқ, бірақ оның әлсіз жері де бар: ол бір ағынды толық GC циклін орындайды. Пайдаланылмаған нысандарды табу үшін жинақтауға болатын аппараттық құралдың барлық күші қажет болған кезде, біз бір ағынмен шектелеміз. Java 10 мұны түзетті.Енді GC біз оған қосатын барлық ресурстармен жұмыс істейді (яғни ол көп ағынды болады). Осы мақсатқа жету үшін тіл әзірлеушілері GC үшін жақсы таза интерфейсті жасай отырып, негізгі көздердің МК-дан оқшаулануын жақсартты. Бұл сүйкімділіктің әзірлеушілері, OpenJDK, жаңа GC құруды мүмкіндігінше жеңілдетіп қана қоймай, сонымен қатар жинақтан қажет емес GC-терді жылдам өшіруге мүмкіндік беру үшін codeтағы қоқыстарды арнайы тазалауға мәжбүр болды. Табысқа жетудің негізгі критерийлерінің бірі - барлық жақсартулардан кейін жұмыс жылдамдығының төмендеуінің болмауы. Сондай-ақ қарастырайық: Басқа инновациялар:
  1. Таза қоқыс жинаушы интерфейсі енгізілген. Бұл әртүрлі қоқыс жинағыштардан бастапқы codeты оқшаулауды жақсартады, баламалы коллекторларды тез және ауыртпалықсыз біріктіруге мүмкіндік береді;
  2. JDK көздерін бір репозиторийге біріктіру;
  3. Коллекциялар жаңа әдісті алды - copyOf (Collection) , бұл жинақтың өзгермейтін көшірмесін қайтарады;
  4. Қосымшада (және оның нұсқаларында) жаңа әдіс бар .orElseThrow() ;
  5. Енді JVM құрылғылары олардың Docker контейнерінде жұмыс істейтінін біледі және операциялық жүйенің өзінен сұраудың орнына контейнерге тән конфигурацияны шығарып алады.
Мұнда Java 10-мен толығырақ таныстыру үшін тағы бірнеше материалдар берілген: Бұрын Java-ның кейбір нұсқалары 1.x деп аталатыны мені қатты шатастырды. Мен анық айтқым келеді: 9-ға дейінгі Java нұсқаларында басқа атау схемасы болды. Мысалы, Java 8-ді 1.8 , Java 5 - 1.5 және т.б. деп те атауға болады. Ал енді Java 9-дан шығарылымдарға көшумен атау схемасы да өзгергенін және Java нұсқалары енді 1.x префиксі болмайтынын көреміз. . Бұл бірінші бөлімнің соңы: біз java 8-10 жаңа қызықты мүмкіндіктерін қарастырдық. Ең соңғысымен танысуымызды келесі постта жалғастырайық .
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION