Inferens Jenis Sasaran Umum di Jawa

1. Pengenalan

Jenis Inferensi diperkenalkan di Java 5 untuk melengkapi pengenalan generik dan diperluas secara substansial setelah rilis Java, yang juga disebut sebagai Inferensi Jenis-Sasaran Umum.

Dalam tutorial ini, kita akan meneroka konsep ini dengan contoh kod.

2. Generik

Generik memberi kami banyak faedah seperti peningkatan keselamatan jenis, mengelakkan kesalahan pemutus jenis dan algoritma generik. Anda boleh membaca lebih lanjut mengenai generik dalam artikel ini.

Walau bagaimanapun, pengenalan generik menyebabkan perlunya menulis kod boilerplate kerana perlunya melewati parameter jenis . Beberapa contoh adalah:

Map
    
      mapOfMaps = new HashMap
     
      (); List strList = Collections.emptyList(); List intList = Collections.emptyList();
     
    

3. Jenis Inferensi Sebelum Java 8

Untuk mengurangkan keterlambatan kode yang tidak perlu, Jenis Inferensi diperkenalkan ke Java yang merupakan proses menyimpulkan secara automatik jenis data yang tidak ditentukan dari ekspresi berdasarkan maklumat kontekstual.

Sekarang, kita boleh menggunakan jenis dan kaedah generik yang sama tanpa menentukan jenis parameter. Penyusun secara automatik memasukkan jenis parameter apabila diperlukan.

Kita dapat melihat kod yang sama menggunakan konsep baru:

List strListInferred = Collections.emptyList(); List intListInferred = Collections.emptyList(); 

Dalam contoh di atas, berdasarkan jenis pulangan dijangka Senarai dan Senarai , pengkompil adalah dapat membuat kesimpulan parameter jenis kepada kaedah generik berikut:

public static final  List emptyList() 

Seperti yang kita lihat, kod yang dihasilkan adalah ringkas. Sekarang, kita boleh memanggil kaedah generik sebagai kaedah biasa jika parameter jenis dapat disimpulkan.

Di Java 5, kita dapat melakukan Type-Inference dalam konteks tertentu seperti yang ditunjukkan di atas.

Java 7 memperluas konteks di mana ia dapat dilakukan. Ia memperkenalkan operator berlian. Anda mungkin membaca lebih lanjut mengenai pengendali berlian dalam artikel ini.

Sekarang, kita dapat melakukan operasi ini untuk pembina kelas generik dalam konteks tugasan. Salah satu contohnya ialah:

Map
    
      mapOfMapsInferred = new HashMap();
    

Di sini, Java Compiler menggunakan jenis tugasan yang diharapkan untuk menyimpulkan parameter jenis ke konstruktor HashMap .

4. Inferens Jenis Sasaran Umum - Java 8

Java 8 memperluas skop Jenis Inferens. Kami merujuk kepada kemampuan inferensi yang diperluas ini sebagai Inferensi Jenis Sasaran Umum. Anda boleh membaca butiran teknikal di sini.

Java 8 juga memperkenalkan Lambda Expressions. Lambda Expressions tidak mempunyai jenis eksplisit. Jenis mereka disimpulkan dengan melihat jenis sasaran konteks atau situasi. Jenis Sasaran ekspresi adalah jenis data yang diharapkan oleh Java Compiler bergantung pada tempat ekspresi itu muncul.

Java 8 menyokong inferensi menggunakan Target-Type dalam konteks kaedah. Apabila kita menggunakan kaedah generik tanpa argumen jenis eksplisit, penyusun dapat melihat kaedah pemanggilan dan deklarasi kaedah yang sesuai untuk menentukan jenis argumen (atau argumen) yang menjadikan pemohon tersebut berlaku.

Mari kita perhatikan contoh kod:

static  List add(List list, T a, T b) { list.add(a); list.add(b); return list; } List strListGeneralized = add(new ArrayList(), "abc", "def"); List intListGeneralized = add(new ArrayList(), 1, 2); List numListGeneralized = add(new ArrayList(), 1, 2.0);

In the code, ArrayList does not provide the type argument explicitly. So, the compiler needs to infer it. First, the compiler looks into the arguments of the add method. Then, it looks into the parameters passed at different invocations.

It performs invocation applicability inference analysis to determine whether the method applies to these invocations. If multiple methods are applicable due to overloading, the compiler would choose the most specific method.

Then, the compiler performs invocation type inference analysis to determine the type arguments.The expected target types are also used in this analysis. It deduces the arguments in the three instances as ArrayList, ArrayList and ArrayList.

Target-Type inference allows us to not specify types for lambda expression parameters:

List intList = Arrays.asList(5, 2, 4, 2, 1); Collections.sort(intList, (a, b) -> a.compareTo(b)); List strList = Arrays.asList("Red", "Blue", "Green"); Collections.sort(strList, (a, b) -> a.compareTo(b));

Here, the parameters a and b do not have explicitly defined types. Their types are inferred as Integer in the first Lambda Expression and as String in the second.

5. Conclusion

Dalam artikel ringkas ini, kami mengkaji Jenis Inferensi, bahawa bersama dengan generik dan Lambda Expression memungkinkan kami menulis kod Java yang ringkas.

Seperti biasa, kod sumber lengkap boleh didapati di Github.