Apa yang diharapkan dari Jawa pada tahun 2020?

2020 sudah berjalan lancar, mari kita bahas perubahan apa di dunia Jawa yang menunggu kita tahun ini. Artikel ini akan mencantumkan tren utama Java dan JDK. Dan saya akan senang dengan tambahan dari pembaca di komentar.

Segera buat reservasi bahwa artikel tersebut lebih merupakan karakter pencari fakta. Rincian tentang setiap topik yang dibahas dapat ditemukan di situs web proyek yang sesuai atau dalam publikasi di sumber terbuka.

gambar

Jadi, mari kita mulai. Sayangnya, Anda harus segera mengecewakan mereka yang tidak mengikuti siklus rilis Java terlalu banyak, tetapi yang sedang menunggu program dukungan jangka panjang (LTS). Tahun ini kami menunggu rilis dengan hanya siklus hidup dukungan singkat (STS).
Yang pertama kami akan mempertimbangkan rilis JDK 14 mendatang, yang harus dirilis pada pertengahan Maret. Dalam siklus rilis ini, sebanyak 16 JEP diklaim. Berikut daftar lengkapnya:
305:Pencocokan Pola sebagai contoh (Pratinjau)
343:Alat Pengemasan (Inkubator)
345:Alokasi Memori NUMA-Sadar untuk G1
349:Streaming Acara JFR
352:Buffer Byte Non-Volatile Dipetakan
358:NullPointerExceptions yang bermanfaat
359:Rekaman (Pratinjau)
361:Alihkan Ekspresi (Standar)
362:Mengurangi Port Solaris dan SPARC
363:Hapus Kolektor Sampah Sapu Markus Menyapu (CMS)
364:ZGC pada macOS
365:ZGC di Windows
366:Deprecate the ParallelScavenge + SerialOld GC Combination
367:Hapus Alat dan API Pack200
368:Blok Teks (Pratinjau Kedua)
370:API Akses Memori Asing (Inkubator)

Banyak JEP dari daftar ini banyak dibahas di konferensi Joker 2019. Saya akan fokus pada yang menurut saya paling menarik.

Pencocokan Pola sebagai contoh (Pratinjau)


JEP panjang akhirnya keluar di Preview. Saya pikir jika Anda adalah seorang programmer berlatih yang telah menulis kode Java selama bertahun-tahun, maka Anda telah menemukan rasa sakit ini lebih dari sekali:

if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase());
}

Jika Anda menulis atau menulis kode juga di Kotlin, maka rasa sakit karena melihat kode Java sedikit lebih buruk. Peserta proyek Amber akan memberi kami visi Pencocokan Pola di Jawa, yang seharusnya mengurangi rasa sakit ini. Dengan munculnya Java 14, kita dapat menulis ulang contoh sebagai berikut:

if (obj instanceof String s) {
   System.out.println(s.toUpperCase());
}

Tampaknya add-on tidak begitu berharga - kami menyimpan satu baris kode. Tetapi misalkan kita ingin melakukan hal berikut:

if (obj instanceof String) {
    String s = (String) obj;
    if (s.contains(“prefix_”)) {
       return s.toUpperCase();
    }
}
return null;

Terlihat tebal, bukan? Mari kita coba hal yang sama, tetapi dengan Pencocokan Pola.

return (obj instanceof String s) && s.contains(“prefix_”) ? s.toUpperCase() : null;

Jadi jelas akan lebih baik. Tetapi ingat bahwa status fungsi ini adalah Pratinjau. Mari kita lihat perubahan apa dari waktu ke waktu. Bagi saya, itu pasti akan membuat hidup saya lebih baik.

NullPointerExceptions yang bermanfaat


2020 ada di halaman, dan Anda masih menulis sehingga NullPointerExceptions terbang keluar untuk Anda? Jangan khawatir, Anda mungkin bukan satu-satunya. Goetz Lindenmaier dan Ralf Schmelter tidak menyarankan cara baru untuk menjauh dari NullPointerExceptions (Opsional masih bersama kami), tetapi mereka mengusulkan untuk meningkatkan proses debugging aplikasi untuk memahami persis di mana letak nol. Jadi, mari kita bayangkan kita menulis kode pada jam lima ... pada malam hari, tentu saja. Dan kami menulis fungsi ini:

public String getStreetFromRequest(Request request) {
   return request.getAddress().getStreet().toUpperCase();
}

Tidak buruk, tetapi mereka benar-benar lupa untuk menempatkan penjelasan @Nullable dan @Nonnull dan memeriksa alamat di bidang yang dikirimkan. Mendapat NullPointerException. Apa yang dikatakan pengecualian itu kepada kita?

Exception in thread "main" java.lang.NullPointerException
	at Program.getStreetFromRequest(Program.java:10)
	at Program.main(Program.java:6)

Sayangnya, kita hanya melihat satu baris, satu kelas dan satu tumpukan. Di mana tepatnya null kembali ke? Mungkin ini permintaan? Mungkin getAddress () dikembalikan nol? Atau mungkin getStreet ()? Ya, rantai panggilan terkadang sakit.

Para penulis JEP mengusulkan solusi: ketika melempar pengecualian, itu seharusnya memotong stack untuk menentukan di mana tepatnya null dikembalikan, dan kemudian menampilkan nama variabel / metode. Mari kita coba Java 14 dengan opsi -XX: + ShowCodeDetailsInExceptionMessages. Kami memulai dan sedikit berbeda:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because the return value of "Address.getStreet()" is null
	at Program.getStreetFromRequest(Program.java:10)
	at Program.main(Program.java:6)

Sekarang kita tahu bahwa pemrograman malam tidak membawa kebaikan (tetapi kadang-kadang mengarah pada penyelesaian tugas tepat waktu), dan dalam program kami kami lupa bahwa alamatnya bukan bidang yang wajib diisi.

Rekaman (Pratinjau)


Masih menghasilkan getter / setter / equals / hashCode dengan ide? Maka JEP ini akan mendatangi Anda!
Kelas data jauh dari tempat terakhir dalam kehidupan pengembang perangkat lunak aplikasi. Setiap kali kita harus membuat metode kelas Data menggunakan IDE favorit kita, atau menggunakan berbagai plugin waktu kompilasi untuk menghasilkan metode yang diperlukan, seperti lombok.

Akibatnya, kami memiliki banyak kode yang mirip dengan ini:

public class Request {
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
       this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Request request = (Request) o;
        return Objects.equals(address, request.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(address);
    }

    @Override
    public String toString() {
        return "Request{" +
                "address=" + address +
                '}';
    }
}

Atau semacamnya:
@Data
@AllArgsConstructor
public class Request {
    private Address address;
}

Di Jawa 14, anggota proyek Amber mengusulkan sintaks baru untuk membuat kelas data. Untuk melakukan ini, gunakan catatan kata kunci baru. Sintaks untuk Record sedikit berbeda dari untuk deskripsi kelas atau enum, dan sedikit mirip dengan Kotlin. Kode di atas dapat ditulis ulang sebagai berikut:

public record Request(Address address) {
}

Semua bidang rekaman memiliki pengubah pribadi dan final secara default. Catatan itu sendiri adalah kelas final dan tidak dapat diwarisi dari kelas lain, tetapi dapat mengimplementasikan antarmuka. Di kelas rekaman dari kotak kita dapatkan: metode getters, konstruktor publik, parameter yang semuanya adalah bidang rekaman dalam urutan deskripsi, sama dengan / kode hash dan toString. Dari hal yang tidak menyenangkan: kami tidak dapat menambahkan bidang ke catatan, kecuali yang ditentukan setelah nama kelas. Misalnya, kode ini akan menghasilkan kesalahan:

public record Request(Address address) {
   private final String anotherParameter; // compilation error
}

Blok Teks (Pratinjau Kedua)


Blok teks dirilis sebagai pratinjau kembali di Jawa 13. Kami pengguna memutar, memutar, dan memberikan umpan balik (Saya sangat yakin bahwa Anda sudah menggunakan Java 13 dengan pratinjau). Akibatnya, pembuat Java membuat perubahan kecil pada blokir teks. Pertama, kita sekarang dapat secara eksplisit menunjukkan di mana garis berakhir, dengan meletakkan escapesequence di baris kami. Berikut ini sebuah contoh:

public static void main(String[] args) {
        final var test = """
                This is the long text block with escape string \s
                that is really well done            \s
                """;
        System.out.println(test);
}

Sekarang kita secara eksplisit mengatur semua spasi ke karakter dan semua karakter ruang akan disimpan ke karakter.

Kedua, sekarang kita dapat membungkus baris panjang blok teks tanpa menerima \ n karakter di baris terakhir. Untuk melakukan ini, kita hanya perlu menambahkan \ pada jeda baris. Seperti apa bentuknya:

public static void main(String[] args) {
        final var test = """
                This is the long text block with escape string \
                that is really well-done functional            
                """;
System.out.println(test);

Setelah dieksekusi, kita mendapatkan baris berikut: "Ini adalah blok teks panjang dengan escape string yang benar-benar berfungsi dengan baik".

Tambahan yang bagus, menurut saya. Saya benar-benar berharap dapat menerjemahkan fungsi ini ke dalam standar.
Semua fitur yang kami ulas kemungkinan akan dibahas secara luas di konferensi mendatang. Beberapa dari mereka telah dibahas di Joker 2019. Pastikan untuk memeriksa pembicaraan Joker 2019 tentang "Evolusi fitur di Jawa 13 dan seterusnya" oleh Cay Horstmann.

Dan beberapa hal yang lebih menarik.


Ada dua item menarik di daftar JEP di inkubator. Untuk memulainya, kita akan memiliki alat universal yang akan membuat installer untuk berbagai sistem operasi (well, akhirnya, saya ingin memberi tahu mereka yang menari-nari saat memasang program pada Windows). Jpacker akan dapat membuat installer msi / exe untuk Windows, paket macOS dan rpm / deb untuk Linux. Mari kita lihat apa yang terjadi, tetapi dalam kasus-kasus langka ketika saya melakukan sesuatu untuk desktop, saya secara pribadi menderita dari kenyataan bahwa saya tidak memiliki alat reguler untuk memasang installer.

Yang lebih menjanjikan adalah API baru untuk mengakses "Memori Asing", mis. segala jenis memori asli atau persisten. API ini terutama bermanfaat untuk pembuat basis data Java atau pembuat kerangka kerja seperti Netty, misalnya. Mereka, menggunakan Unsafe dan ByteBuffer, mengoptimalkan akses memori dengan off-heap sebanyak mungkin.

Rilis selanjutnya. Sukacita dan frustrasi


Pada bulan September, kami sedang menunggu rilis dukungan jangka pendek di nomor 15. Daftar JEP yang akan dimasukkan dalam rilis final masih terbuka. Sejauh ini, Anda dapat melihat banyak perubahan berbeda dalam bahasa itu sendiri, di perpustakaan standar dan mesin virtual.
Berikut adalah daftar kandidat (dapat berubah dengan cepat, lihat di sini: bugs.openjdk.java.net/secure/Dashboard.jspa?selectPageId=19114 ):
111:Additional Unicode Constructs for Regular Expressions
116:Extended Validation SSL Certificates
134:Intuitive Semantics for Nested Reference Objects
152:Crypto Operations with Network HSMs
198:Light-Weight JSON API
218:Generics over Primitive Types
300:Augment Use-Site Variance with Declaration-Site Defaults
301:Enhanced Enums
302:Lambda Leftovers
303:Intrinsics for the LDC and INVOKEDYNAMIC Instructions
306:Restore Always-Strict Floating-Point Semantics
338:Vector API (Incubator)
339:Compiler Intrinsics for Java SE APIs
348:Compiler Intrinsics for Java SE APIs
356:Enhanced Pseudo-Random Number Generators
360:Sealed Types (Preview)
371:Hidden Classes

Seperti yang Anda lihat, daftar ini masih tidak memiliki banyak hal yang diharapkan. Pertama-tama, bagi saya itu adalah Project Loom. Gagasan paralelisme struktural telah sangat populer dalam beberapa tahun terakhir. Coroutine dapat sangat menyederhanakan tugas komputasi paralel yang kompetitif dan pelaksanaan tugas yang tidak sinkron. Contoh-contoh hebat dalam mengimplementasikan ide ini dapat dilihat, misalnya, dalam bahasa Kotlin (coroutine) dan Go (goroutine). Jawa juga mengeksplorasi ide paralelisme struktural, dan sudah ada hasil pertama. Untuk saat ini, Anda hanya dapat melihatnya dengan mengkompilasi JDK dari repositori proyek.

Proyek yang sangat menjanjikan, Valhalla, juga belum memuaskan kami dengan preview apa pun. Sebuah laporan menarik tentang proyek ini dipresentasikan pada Joker 2019 ("Apakah Java memerlukan tipe" inline "? Pandangan sempit tentang insinyur kinerja pada proyek Valhalla" oleh Sergey Kuksenko).

Apa yang disajikan dalam daftar?

Hal pertama yang menarik perhatian Anda adalah JSON API. Pertanyaan segera muncul - mengapa? Jelas tidak ada jawaban yang pasti. Bagian JEP tentang motivasi mengatakan bahwa JSON telah menjadi sesuatu yang standar untuk layanan web, dan sekarang saatnya untuk mengadaptasi Java SE untuk berinteraksi dengan JSON (walaupun sekarang ada banyak perpustakaan untuk mem-parsing JSON sekarang). Penjelasan yang paling mungkin adalah kemampuan pengembang perangkat lunak untuk menggunakan API inti kecil untuk mengurangi ukuran bundel tanpa harus menyeret Jackson yang berat ke diri mereka sendiri. Saya tidak melihat penjelasan lain, karena tidak akan ada penyatuan data.

Kami juga melihat sejumlah peningkatan terkait dengan API kriptografi. Untuk memulai, pengembang JDK ingin memperluas proses memvalidasi sertifikat SSL dengan menambahkan dukungan untuk sertifikat EVSSL. Menggunakan API ini di Java, Anda dapat menentukan apakah koneksi SSL dipercaya oleh sertifikat EV (Extended Validation). Sertifikat EVSSL sesuai dengan pedoman akan didukung sepenuhnya. Algoritma kriptografi EdDSA baru juga akan ditambahkan dan verifikasi kriptografi HSM akan ditingkatkan.

Dari hal-hal bahasa, saya akan memilih implementasi Generics pada primitif. Setiap orang yang pernah diprogram dalam C # dan beralih ke Jawa, mungkin dapat mengajukan pertanyaan, mengapa Anda tidak dapat melakukan tipe Generik pada primitif. Jawabannya sederhana - Generik hanya berfungsi dengan objek, dan primitif bukan objek dan, khususnya, tidak mewarisi kelas Object. Ini bukan tahun pertama perang telah dilancarkan dalam masalah ini, dan Brian Goetz kembali ke sana lagi. Tidak ada yang istimewa untuk dijelaskan sejauh ini. Tugasnya jelas - untuk mendukung konstruksi seperti Daftar. Tetapi bahkan saat ini ada 13 pertanyaan terbuka yang perlu diselesaikan sebelum mengimplementasikan fungsi ini. Jujur, saya bertanya-tanya bagaimana seri ini akan berakhir.

Dan hal terakhir yang ingin saya sentuh adalah tipe yang disegel. Ini adalah langkah selanjutnya menuju pencocokan pola. Jenis Tertutup adalah ekstensi bahasa yang mengimplementasikan segel (pengubah) dan mengizinkan kata kunci untuk kelas atau antarmuka.

Menggunakan kelas tersegel, kami membatasi jumlah keturunan hanya untuk kelas-kelas yang ditentukan dalam izin (pembatasan eksplisit) atau di unit kompilasi yang sama (file). Deskripsi contoh kelas tersegel:

// 
public abstract sealed class Base {
   public static class ChildA extends Base{}
   public static class ChildB extends Base{}
}

// 
public sealed interface BaseInterface permits ChildC, ChildD{
}

//  
public class ChildC implements BaseInterface {
}
//  
public class ChildD implements BaseInterface {
}

Modifier disegel memastikan bahwa hanya keturunan terbatas hingga dapat memperluas kelas dasar atau mengimplementasikan antarmuka. Properti ini dapat digunakan saat memproses objek dari kelas-kelas ini. Dan, tentu saja, ini adalah kandidat yang bagus untuk digunakan dalam pernyataan switch dengan pencocokan pola.

Kesimpulan


Kami melihat berbagai inovasi JDK tahun ini. Beberapa dari mereka akan menembak, beberapa tidak. Tapi yang paling penting di JDK baru, saya berharap optimasi kecil (atau tidak begitu) baru yang membuat program kami lebih cepat dengan setiap rilis gratis. Dan jika Anda berada di Joker terakhir 2019 dan mengunjungi laporan Tagir Valeev Java 9-14: Optimalisasi kecil, maka kemungkinan besar, seperti saya, Anda terkesan dengan pekerjaan yang dilakukan kontributor untuk mengoptimalkan JDK. Hasilnya tidak terlihat pada pandangan pertama dan tidak tercermin dalam lebih dari satu JEP, tetapi kami menggunakannya setiap hari.

Good Java rilis untuk kita semua. Jelajahi fitur platform baru, pergi ke konferensi dan ikuti tren.

All Articles