Dalam bahasa C++, terdapat fungsi templat yang sangat berguna, yang boleh menulis versi umum dengan jenis parameter dan membiarkan pengkompil secara automatik menjana versi Khusus untuk jenis yang berbeza. Dalam bahasa Java, terdapat fungsi serupa yang dipanggil generik. Apabila menulis kelas dan kaedah, jenis khusus biasanya digunakan, dan generik boleh digunakan untuk menentukan parameter jenis, supaya kod yang lebih umum boleh ditulis.
Ramai orang percaya bahawa konsep templat C++ dan generik Java adalah setara, tetapi sebenarnya mekanisme pelaksanaannya berbeza sama sekali. Templat C++ ialah satu set arahan makro, dan pengkompil akan membuat salinan kod templat untuk setiap jenis pelaksanaan generik Java adalah berdasarkan konsep "penghapusan jenis", yang pada asasnya adalah gula sintaksis untuk sekatan jenis.
Ambil kelas sokongan sebagai contoh untuk mentakrifkan kelas sokongan universal untuk generik:
/** 通用支撑类 */@Getter@Setter@ToStringpublic class GenericHolder<T> { /** 通用取值 */ private T value; /** 构造函数 */ public GenericHolder() {} /** 构造函数 */ public GenericHolder(T value) { this.value = value; } }
/** 数据提供者接口 */public interface DataProvider<T> { /** 获取数据函数 */ public T getData(); }
/** 浅拷贝函数 */public static <T> T shallowCopy(Object source, Class<T> clazz) throws BeansException { // 判断源对象 if (Objects.isNull(source)) { return null; } // 新建目标对象 T target; try { target = clazz.newInstance(); } catch (Exception e) { throw new BeansException("新建类实例异常", e); } // 拷贝对象属性 BeanUtils.copyProperties(source, target); // 返回目标对象 return target; }Dalam spesifikasi Java, tidak disyorkan untuk menggunakan kad bebas generik "?" Fungsi di atas boleh ditukar kepada:
/** 打印取值函数 */public static void printValue(GenericHolder<?> holder) { System.out.println(holder.getValue()); }/** 主函数 */public static void main(String[] args) { printValue(new GenericHolder<>(12345)); printValue(new GenericHolder<>("abcde")); }5 sempadanApabila menggunakan generik, kita juga boleh menetapkan sempadan atas dan bawah untuk parameter sebenar jenis generik yang diluluskan Contohnya, jenis parameter sebenar hanya dibenarkan untuk lulus dalam jenis kelas induk tertentu atau jenis tertentu daripada subkelas. Pengisytiharan sempadan atas dan bawah bagi jenis generik mesti diletakkan bersama-sama dengan pengisytiharan jenis generik.
/** 打印取值函数 */public static <T> void printValue(GenericHolder<T> holder) { System.out.println(holder.getValue()); }
Kad bebas sempadan atas ialah "lanjutkan", yang boleh menerima jenis yang ditentukan atau subkelasnya sebagai parameter umum. Terdapat juga bentuk khas yang menyatakan bahawa ia bukan sahaja harus menjadi subkelas jenis yang ditentukan, tetapi juga melaksanakan antara muka tertentu. Sebagai contoh: Senarai memanjangkan A> menunjukkan bahawa ini ialah Senarai subkelas A dan objek yang disimpan mestilah A atau subkelas A. Untuk Senarai memanjangkan senarai A> anda tidak boleh menambah A atau objek subkelas A, tetapi hanya boleh mendapatkan objek A.
Kad bebas sempadan bawah (super):
Kad bebas sempadan bawah ialah "super", yang boleh menerima jenis yang ditentukan atau kelas induknya sebagai parameter umum. Contohnya: Senarai super A> menunjukkan bahawa ini ialah Senarai kelas induk A dan objek yang disimpan mestilah A atau superclass A. Untuk Senarai senarai super A> anda boleh menambah A atau objek subkelas A, tetapi anda hanya boleh mendapatkan objek Objek.
Prinsip PECS (Producer Extends Consumer Super):
Apabila menyediakan data sebagai pengeluar (membaca keluar), adalah sesuai untuk menggunakan kad bebas sempadan atas (melanjutkanSebagai pengguna yang menggunakan data (); membaca dalam) Apabila menulis), adalah sesuai untuk menggunakan kad bebas sempadan bawah (super).
Dalam pengekodan harian, kad bebas sempadan atas (lanjutan) lebih biasa digunakan, yang digunakan untuk mengehadkan kelas induk bagi jenis generik. Kod contoh adalah seperti berikut:
Atas ialah kandungan terperinci Apakah kesan ciri pelindung jenis generik dalam Java pada kod?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!