Generik Java


Generik Java (generik) ialah ciri baharu yang diperkenalkan dalam JDK 5. Generik menyediakan mekanisme pengesanan keselamatan jenis masa kompilasi, yang membolehkan pengaturcara mengesan jenis haram pada masa penyusunan.


Intipati generik ialah jenis parameter, yang bermaksud bahawa jenis data yang dikendalikan ditentukan sebagai parameter.

Andaikan kita mempunyai keperluan seperti itu: tulis kaedah pengisihan yang boleh mengisih tatasusunan integer, tatasusunan rentetan atau mana-mana jenis tatasusunan lain Bagaimana untuk melaksanakannya?

Jawapannya ialah menggunakan Java Generics.

Menggunakan konsep generik Java, kita boleh menulis kaedah generik untuk mengisih tatasusunan objek. Kemudian, panggil kaedah generik ini untuk mengisih tatasusunan integer, tatasusunan terapung, tatasusunan rentetan, dsb.


Kaedah generik

Anda boleh menulis kaedah generik yang boleh menerima pelbagai jenis parameter apabila dipanggil. Bergantung pada jenis parameter yang dihantar kepada kaedah generik, pengkompil mengendalikan setiap panggilan kaedah dengan sewajarnya.

Berikut ialah peraturan untuk mentakrifkan kaedah generik:

  • Semua pengisytiharan kaedah generik mempunyai bahagian pengisytiharan parameter jenis (dibataskan oleh kurungan sudut) yang mengisytiharkan bahagian parameter jenis sebelum kaedah mengembalikan jenis (<E> dalam contoh di bawah).

  • Setiap bahagian pengisytiharan parameter jenis mengandungi satu atau lebih jenis parameter, dipisahkan dengan koma. Parameter generik, juga dipanggil pembolehubah jenis, ialah pengecam yang menentukan nama jenis generik.

  • Parameter jenis boleh digunakan untuk mengisytiharkan jenis nilai pulangan dan boleh berfungsi sebagai ruang letak untuk jenis parameter sebenar yang diperoleh melalui kaedah generik.

  • Pengisytiharan badan kaedah generik adalah sama seperti kaedah lain. Ambil perhatian bahawa parameter jenis hanya boleh mewakili jenis rujukan, bukan jenis primitif (seperti int, double, char, dll.).

Contoh

Contoh berikut menunjukkan cara menggunakan kaedah generik untuk mencetak elemen rentetan berbeza:

public class GenericMethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }

    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组

        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组

        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}

Kompilkan kod di atas dan hasil yang sedang dijalankan adalah seperti berikut Ditunjukkan sebagai:

整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O

Parameter jenis terhad:

Mungkin ada kalanya anda ingin mengehadkan julat jenis yang dibenarkan untuk dihantar ke dalam parameter jenis. Sebagai contoh, kaedah yang beroperasi pada nombor mungkin hanya ingin menerima contoh Nombor atau subkelas Nombor. Itulah tujuan parameter jenis terikat.

Untuk mengisytiharkan parameter jenis bersempadan, mula-mula senaraikan nama parameter jenis, diikuti dengan kata kunci lanjutan, dan akhirnya diikuti dengan sempadan atasnya.

Contoh

Contoh berikut menunjukkan cara "melanjutkan" digunakan dalam erti kata umum untuk bermaksud "melanjutkan" (kelas) atau "melaksanakan" (antara muka). Kaedah generik dalam contoh ini mengembalikan nilai maksimum tiga objek setanding.

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

Kompilkan kod di atas dan hasil yang dijalankan adalah seperti berikut:

3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

Kelas generik

Pengisytiharan kelas generik adalah serupa dengan pengisytiharan kelas bukan generik, kecuali bahagian pengisytiharan parameter jenis ditambah selepas nama kelas.

Seperti kaedah generik, bahagian pengisytiharan parameter jenis bagi kelas generik juga mengandungi satu atau lebih parameter jenis, dipisahkan dengan koma. Parameter generik, juga dipanggil pembolehubah jenis, ialah pengecam yang menentukan nama jenis generik. Kerana mereka menerima satu atau lebih parameter, kelas ini dipanggil kelas parameter atau jenis parameter.

Contoh

Contoh berikut menunjukkan cara kita mentakrifkan kelas generik:

public class Box<T> {
   
  private T t;

  public void add(T t) {
    this.t = t;
  }

  public T get() {
    return t;
  }

  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();

    integerBox.add(new Integer(10));
    stringBox.add(new String("php中文网"));

    System.out.printf("整型值为 :%d\n\n", integerBox.get());
    System.out.printf("字符串为 :%s\n", stringBox.get());
  }
}

Kompilkan kod di atas, dan hasil yang dijalankan adalah seperti berikut:

整型值为 :10

字符串为 :php中文网