JavaRush /Blog Java /Random-MS /Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java...

Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java. Bahagian 1

Diterbitkan dalam kumpulan
Anak kucing, hello semua)) Jadi, hari ini kita berada di tahun 2020, dan hanya tinggal sedikit sehingga keluaran Java 14. Anda sepatutnya menjangkakan versi siap pada 17 Mac, kami akan menganalisis perkara yang segar dan menarik di sana selepas fakta itu, tetapi hari ini saya ingin menyegarkan ingatan saya pada versi Java sebelumnya. Apa yang baru yang mereka bawa kepada kita? Jom tengok. Mari kita mulakan semakan dengan Java 8, kerana ia masih agak relevan dan digunakan dalam kebanyakan projek. Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java.  Bahagian 1 - 1Sebelum ini, versi baharu dikeluarkan setiap 3-5 tahun, tetapi baru-baru ini Oracle telah mengambil pendekatan berbeza - "Java baharu setiap enam bulan." Oleh itu, setiap enam bulan kami melihat keluaran ciri. Sama ada baik atau buruk, semua orang melihatnya secara berbeza. Sebagai contoh, saya tidak begitu menyukai ini, kerana versi baharu tidak mempunyai banyak ciri baharu, tetapi pada masa yang sama, versi tumbuh seperti cendawan selepas hujan. Saya berkelip beberapa kali pada projek dengan Java 8, dan Java 16 telah dikeluarkan (tetapi apabila ia jarang keluar, ciri-ciri baru terkumpul, dan akhirnya acara ini telah lama ditunggu-tunggu, seperti hari cuti: semua orang membincangkan tentang barang baru dan anda tidak boleh melewatinya) . Jadi mari kita mulakan!

Jawa 8

Antara Muka Fungsian

Apakah ini? Antara muka berfungsi ialah antara muka yang mengandungi satu kaedah (abstrak) yang tidak dilaksanakan. @FunctionalInterface ialah anotasi pilihan yang diletakkan di atas antara muka sedemikian. Diperlukan untuk menyemak sama ada ia memenuhi keperluan antara muka berfungsi (hanya mempunyai satu kaedah abstrak). Tetapi seperti biasa, kami mempunyai beberapa kaveat: kaedah lalai dan statik tidak termasuk dalam keperluan ini. Oleh itu, boleh terdapat beberapa kaedah sedemikian + satu abstrak, dan antara muka akan berfungsi. Ia juga mungkin mengandungi kaedah kelas Objek yang tidak menjejaskan takrifan antara muka sebagai berfungsi. Saya akan menambah beberapa perkataan tentang kaedah lalai dan statik:
  1. Kaedah dengan pengubah suai lalai membolehkan anda menambah kaedah baharu pada antara muka tanpa melanggar pelaksanaan sedia ada.

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

    Ya, ya, kami menambah kaedah yang dilaksanakan pada antara muka, dan apabila melaksanakan kaedah ini, anda tidak boleh mengatasinya, tetapi menggunakannya sebagai kaedah yang diwarisi. Tetapi jika kelas melaksanakan dua antara muka dengan kaedah yang diberikan, kita akan mempunyai ralat kompilasi, dan jika ia melaksanakan antara muka dan mewarisi kelas dengan kaedah yang sama tertentu, kaedah kelas induk akan bertindih dengan kaedah antara muka dan pengecualian tidak akan berfungsi.

  2. kaedah statik dalam antara muka berfungsi sama seperti kaedah statik dalam kelas. Jangan lupa: anda tidak boleh mewarisi kaedah statik , sama seperti anda tidak boleh memanggil kaedah statik daripada kelas keturunan.

Jadi, beberapa perkataan lagi tentang antara muka berfungsi dan mari teruskan. Berikut ialah senarai utama FI (selebihnya adalah jenisnya):

    Predikat - mengambil beberapa nilai T sebagai hujah, mengembalikan boolean.

    Contoh:boolean someMethod(T t);

  • Pengguna - mengambil hujah jenis T, tidak mengembalikan apa-apa (tidak sah).

    Contoh:void someMethod(T t);

  • Pembekal - tidak mengambil apa-apa sebagai input, tetapi mengembalikan beberapa nilai T.

    Contoh:T someMethod();

  • Fungsi - mengambil parameter jenis T sebagai input, mengembalikan nilai jenis R.

    Contoh:R someMethod(T t);

  • UnaryOperator - mengambil hujah T dan mengembalikan nilai jenis T.

    Contoh:T someMethod(T t);

Strim

Strim ialah cara untuk mengendalikan struktur data dalam gaya berfungsi. Biasanya ini adalah koleksi (tetapi anda boleh menggunakannya dalam situasi lain yang kurang biasa). Dalam bahasa yang lebih mudah difahami, Strim ialah aliran data yang kami proses seolah-olah bekerja dengan semua data pada masa yang sama, dan bukan kekerasan, seperti untuk setiap satu. Mari kita lihat contoh kecil. Katakan kita mempunyai satu set nombor yang ingin kita tapis (kurang daripada 50), meningkat sebanyak 5, dan mengeluarkan 4 nombor pertama daripada yang selebihnya ke konsol. Bagaimana kita akan melakukan ini lebih awal:
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);

}
Nampaknya tidak banyak kod, dan logiknya sudah agak mengelirukan. Mari lihat bagaimana ia akan kelihatan menggunakan strim:
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)

      .filter(x -> x < 50)

      .map(x -> x + 5)

      .limit(4)

      .forEach(System.out::print);
Strim sangat memudahkan kehidupan dengan mengurangkan jumlah kod dan menjadikannya lebih mudah dibaca. Bagi mereka yang ingin mendalami topik ini dengan lebih terperinci, berikut adalah artikel yang bagus (malah saya katakan sangat baik) mengenai topik ini .

Lambda

Mungkin ciri yang paling penting dan lama ditunggu-tunggu ialah penampilan lambdas. Apa itu lambda? Ini ialah blok kod yang boleh dihantar ke tempat yang berbeza supaya ia boleh dilaksanakan kemudian seberapa banyak kali yang diperlukan. Kedengarannya agak mengelirukan, bukan? Ringkasnya, menggunakan lambdas, anda boleh melaksanakan kaedah antara muka berfungsi (sejenis pelaksanaan kelas tanpa nama):
Runnable runnable = () -> { System.out.println("I'm running !");};

new Thread(runnable).start();
Kami melaksanakan kaedah run() dengan cepat dan tanpa birokrasi yang tidak perlu. Dan ya: Runnable ialah antara muka yang berfungsi. Saya juga menggunakan lambdas apabila bekerja dengan aliran (seperti dalam contoh dengan aliran di atas). Kami tidak akan pergi terlalu dalam, kerana kami boleh menyelam agak dalam, saya akan meninggalkan beberapa pautan supaya lelaki yang masih penggali di hati boleh menggali lebih dalam:

untuk setiap

Java 8 mempunyai foreach baharu yang berfungsi dengan aliran data seperti aliran. Berikut ialah contoh:
List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);

someList.forEach(x -> System.out.println(x));
(bersamaan dengan someList.stream().foreach(…))

Rujukan kaedah

Kaedah rujukan ialah sintaks baharu yang berguna yang direka untuk merujuk kaedah sedia ada atau pembina kelas atau objek Java melalui :: Rujukan kaedah terdapat dalam empat jenis:
  1. Pautan kepada pereka bentuk:

    SomeObject obj = SomeObject::new

  2. Rujukan kaedah statik:

    SomeObject::someStaticMethod

  3. Rujukan kepada kaedah bukan statik bagi objek jenis tertentu:

    SomeObject::someMethod

  4. Rujukan kepada kaedah biasa (bukan statik) bagi objek tertentu

    obj::someMethod

Selalunya, rujukan kaedah digunakan dalam strim dan bukannya lambdas (kaedah rujukan lebih pantas daripada lambdas, tetapi lebih rendah dalam kebolehbacaan).
someList.stream()

        .map(String::toUpperCase)

      .forEach(System.out::println);
Bagi mereka yang ingin maklumat lanjut tentang kaedah rujukan:

Masa API

Terdapat perpustakaan baharu untuk bekerja dengan tarikh dan masa - java.time. Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java.  Bahagian 1 - 2API baharu adalah serupa dengan mana-mana Joda-Time. Bahagian paling penting API ini ialah:
  • LocalDate ialah tarikh tertentu, sebagai contoh - 2010-01-09;
  • LocalTime - masa dengan mengambil kira zon waktu - 19:45:55 (bersamaan dengan LocalDate);
  • LocalDateTime - kombo LocalDate + LocalTime - 2020-01-04 15:37:47;
  • ZoneId - mewakili zon masa;
  • Jam - menggunakan jenis ini anda boleh mengakses masa dan tarikh semasa.
Berikut adalah beberapa artikel yang sangat menarik mengenai topik ini:

Pilihan

Ini ialah kelas baharu dalam pakej java.util , pembungkus nilai yang muslihatnya ialah ia juga boleh mengandungi null dengan selamat . Menerima pilihan: Jika kami melepasi nullOptional<String> someOptional = Optional.of("Something"); dalam Optional.of , kami akan mendapat NullPointerException kegemaran kami . Untuk kes sedemikian mereka menggunakan: - dalam kaedah ini anda tidak perlu takut batal. Seterusnya, buat Pilihan pada mulanya kosong: Untuk menyemak sama ada ia kosong, gunakan: akan mengembalikan benar atau palsu kepada kami. Lakukan tindakan tertentu jika terdapat nilai, dan lakukan apa-apa jika tiada nilai: Kaedah songsang yang mengembalikan nilai yang diluluskan jika Pilihan kosong (semacam pelan sandaran): Anda boleh meneruskan untuk masa yang sangat lama ( mujurlah, Optional telah menambah kaedah dengan kedua-dua tangan yang murah hati), tetapi kami tidak akan memikirkan perkara ini. Adalah lebih baik bagi saya untuk meninggalkan beberapa pautan sebagai permulaan: 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")); Kami meneliti inovasi paling terkenal di Java 8 - bukan itu sahaja. Jika anda ingin mengetahui lebih lanjut, maka saya tinggalkan ini untuk anda:

Jawa 9

Jadi, pada 21 September 2017, dunia menyaksikan JDK 9. Java 9 ini dilengkapi dengan set ciri yang kaya. Walaupun tiada konsep bahasa baharu, API baharu dan arahan diagnostik pasti akan menarik minat pembangun. Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java.  Bahagian 1 - 4

JShell (REPL - gelung baca-eval-cetak)

Ini ialah pelaksanaan Java bagi konsol interaktif yang digunakan untuk menguji kefungsian dan menggunakan binaan berbeza dalam konsol, seperti antara muka, kelas, enum, operator, dsb. Untuk melancarkan JShell, anda hanya perlu menulis jshell di terminal. Kemudian kita boleh menulis apa sahaja yang dibenarkan oleh imaginasi kita: Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java.  Bahagian 1 - 5Menggunakan JShell, anda boleh mencipta kaedah peringkat atas dan menggunakannya dalam sesi yang sama. Kaedah akan berfungsi sama seperti kaedah statik, kecuali kata kunci statik boleh ditinggalkan. Baca lebih lanjut dalam manual Java 9 REPL (JShell) .

Persendirian

Bermula dengan versi 9 Java, kami mempunyai peluang untuk menggunakan kaedah persendirian dalam antara muka (kaedah lalai dan statik, kerana kami tidak boleh mengatasi yang lain kerana akses yang tidak mencukupi). private static void someMethod(){} try-with-resources Keupayaan untuk mengendalikan pengecualian Try-With-Resources telah ditingkatkan:
BufferedReader reader = new BufferedReader(new FileReader("....."));
  try (reader2) {
  ....
}

Modulariti ( Jigsaw )

Modul ialah sekumpulan pakej dan sumber yang berkaitan bersama-sama dengan fail deskriptor modul baharu. Pendekatan ini digunakan untuk melonggarkan gandingan kod. Gandingan longgar ialah faktor utama untuk kebolehselenggaraan dan kebolehlanjutan kod. Modulariti dilaksanakan pada tahap yang berbeza:
  1. Bahasa pengaturcaraan.
  2. Mesin maya.
  3. API java standard.
JDK 9 dilengkapi dengan 92 modul: kita boleh menggunakannya atau mencipta modul sendiri. Berikut adalah beberapa pautan untuk melihat lebih mendalam:

Koleksi tidak boleh ubah

Di Java 9, menjadi mungkin untuk mencipta dan mengisi koleksi dengan satu baris, sambil menjadikannya tidak berubah (sebelum ini, untuk mencipta koleksi tidak berubah, kami perlu mencipta koleksi, mengisinya dengan data, dan memanggil kaedah, sebagai contoh, Collections.unmodifiableList). Contoh ciptaan sedemikian: List someList = List.of("first","second","third");

Inovasi lain:

  • dikembangkan Pilihan (kaedah baharu ditambah);
  • antara muka ProcessHandle dan ProcessHandle kelihatan mengawal tindakan sistem pengendalian;
  • G1 - pemungut sampah lalai;
  • Pelanggan HTTP dengan sokongan untuk kedua-dua protokol HTTP/2 dan WebSocket;
  • Aliran diperluaskan;
  • menambah rangka kerja API Aliran Reaktif (untuk pengaturcaraan reaktif);
Untuk rendaman yang lebih lengkap dalam Java 9, saya menasihati anda untuk membaca:

Jawa 10

Jadi, enam bulan selepas keluaran Java 9, pada Mac 2018 (saya masih ingat seperti semalam), Java 10 muncul di tempat kejadian. Dari 8 hingga 13: gambaran keseluruhan lengkap versi Java.  Bahagian 1 - 6

var

Sekarang kita tidak perlu menyediakan jenis data. Kami menandakan mesej sebagai var dan pengkompil menentukan jenis mesej mengikut jenis pemula yang terdapat di sebelah kanan. Ciri ini hanya tersedia untuk pembolehubah tempatan dengan pemula: ia tidak boleh digunakan untuk hujah kaedah, jenis pulangan, dsb., kerana tiada pemula untuk dapat menentukan jenis. Contoh var (untuk jenis String):
var message = "Some message…..";
System.out.println(message);
var bukan kata kunci: ia pada asasnya adalah nama jenis terpelihara, sama seperti int . Faedah var adalah hebat: pengisytiharan jenis mengambil banyak perhatian tanpa membawa sebarang faedah, dan ciri ini akan menjimatkan masa. Tetapi pada masa yang sama, jika pembolehubah diperoleh daripada rantaian kaedah yang panjang, kod tersebut menjadi kurang boleh dibaca, kerana ia tidak jelas dengan serta-merta jenis objek yang terletak di sana. Didedikasikan kepada mereka yang ingin menjadi lebih biasa dengan fungsi ini:

Pengkompil JIT (GraalVM)

Tanpa berlengah lagi, izinkan saya mengingatkan anda bahawa apabila anda menjalankan arahan javac, aplikasi Java disusun daripada kod Java ke dalam kod bait JVM, yang merupakan perwakilan binari aplikasi. Tetapi pemproses komputer biasa tidak boleh hanya melaksanakan kod bait JVM. Untuk program JVM anda berfungsi, anda memerlukan pengkompil lain untuk kod bait ini, yang ditukar kepada kod mesin yang sudah boleh digunakan oleh pemproses. Berbanding dengan javac, pengkompil ini jauh lebih kompleks, tetapi juga menghasilkan kod mesin berkualiti tinggi. Pada masa ini, OpenJDK mengandungi mesin maya HotSpot, yang seterusnya mempunyai dua penyusun JIT utama. Yang pertama, C1 ( pengkompil klien ), direka untuk operasi kelajuan yang lebih tinggi, tetapi pengoptimuman kod mengalami masalah. Yang kedua ialah C2 (penyusun pelayan). Kelajuan pelaksanaan terjejas, tetapi kodnya lebih dioptimumkan. Bilakah yang mana satu digunakan? C1 bagus untuk aplikasi desktop di mana jeda JIT yang lama tidak diingini, dan C2 bagus untuk program pelayan yang berjalan lama di mana menghabiskan lebih banyak masa untuk penyusunan agak boleh ditanggung. Kompilasi berbilang peringkat ialah apabila kompilasi mula-mula melalui C1, dan hasilnya melalui C2 (digunakan untuk pengoptimuman yang lebih besar). GraalVM ialah projek yang dicipta untuk menggantikan HotSpot sepenuhnya. Kita boleh menganggap Graal sebagai beberapa projek berkaitan: pengkompil JIT baharu untuk HotSpot dan mesin maya polyglot baharu. Keistimewaan pengkompil JIT ini ialah ia ditulis dalam Java. Kelebihan pengkompil Graal ialah keselamatan, iaitu, bukan ranap, tetapi pengecualian, bukan kebocoran memori. Kami juga akan mempunyai sokongan IDE yang baik, dan kami akan dapat menggunakan penyahpepijat, pemprofil atau alatan mudah yang lain. Di samping itu, pengkompil mungkin bebas daripada HotSpot, dan ia akan dapat mencipta versi yang disusun JIT sendiri yang lebih pantas. Untuk penggali:

Selari G1

Pengumpul sampah G1 sememangnya keren, tidak syak lagi mengenainya, tetapi ia juga mempunyai titik lemah: ia melakukan kitaran GC penuh satu benang. Pada masa anda memerlukan semua kuasa perkakasan yang anda boleh kumpulkan untuk mencari objek yang tidak digunakan, kami terhad kepada satu utas. Java 10 membetulkannya. Kini GC kini berfungsi dengan semua sumber yang kami tambahkan padanya (iaitu, ia menjadi berbilang benang). Untuk mencapai matlamat ini, pembangun bahasa telah menambah baik pengasingan sumber utama daripada GC, mewujudkan antara muka bersih yang bagus untuk GC. Pembangun kecomelan ini, OpenJDK, terpaksa membersihkan tempat pembuangan secara khusus dalam kod agar bukan sahaja memudahkan penciptaan GC baharu sebanyak mungkin, tetapi juga untuk membolehkan anda melumpuhkan GC yang tidak diperlukan dengan cepat daripada pemasangan. Salah satu kriteria utama untuk berjaya ialah ketiadaan pengurangan dalam kelajuan operasi selepas semua penambahbaikan ini. Jom tengok juga: Inovasi lain:
  1. Antara Muka Pengumpul Sampah yang bersih diperkenalkan. Ini menambah baik pengasingan kod sumber daripada pengumpul sampah yang berbeza, menjadikannya mungkin untuk menyepadukan pengumpul alternatif dengan cepat dan tanpa rasa sakit;
  2. Menggabungkan sumber JDK ke dalam satu repositori;
  3. Koleksi menerima kaedah baharu - copyOf (Collection) , yang mengembalikan salinan koleksi ini yang tidak boleh diubah;
  4. Pilihan (dan variannya) mempunyai kaedah baharu .orElseThrow() ;
  5. Mulai sekarang, JVM sedar bahawa mereka berjalan dalam bekas Docker dan akan mengambil konfigurasi khusus kontena dan bukannya menanyakan sistem pengendalian itu sendiri.
Berikut adalah beberapa lagi bahan untuk pengenalan yang lebih terperinci kepada Java 10: Saya pernah sangat keliru dengan fakta bahawa beberapa versi Java dipanggil 1.x. Saya ingin menjelaskan: Versi Java sebelum 9 hanya mempunyai skema penamaan yang berbeza. Sebagai contoh, Java 8 juga boleh dipanggil 1.8 , Java 5 - 1.5 , dsb. Dan kini kita melihat bahawa dengan peralihan kepada keluaran dari Java 9, skema penamaan juga telah berubah, dan versi Java tidak lagi diawali dengan 1.x . Ini adalah penghujung bahagian pertama: kami membincangkan ciri menarik baharu java 8-10. Jom sambung perkenalan dengan yang terbaru di post seterusnya .
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION