Pemadaman generik
Seperti yang kita semua tahu, generik Java hanya sah pada masa penyusunan, dan jenis generik akan dipadamkan semasa runtime, iaitu List< ;String> ; dan Senarai
Mengapa memilih mekanisme pelaksanaan ini? Tidak bolehkah anda memadamkannya? 10 tahun selepas kelahiran Java saya ingin melaksanakan konsep yang serupa dengan templat C++, iaitu generik. Pustaka kelas Java ialah aset yang sangat berharga dalam ekosistem Java Ia mesti memastikan keserasian ke belakang (iaitu, kod dan fail kelas sedia ada masih sah) dan keserasian pemindahan (kod umum dan kod tidak umum boleh memanggil satu sama lain di atas Disebabkan oleh dua latar belakang dan pertimbangan ini, pereka Java menggunakan kaedah pelaksanaan kompromi "jenis pemadaman".
Pada masa yang sama, terdapat mekanisme "perangkap" sedemikian yang menghalang kami daripada mendapatkan jenis parameter generik tertentu sesuka hati semasa masa jalan.
TypeToken
Gunakan
Pelajar yang telah menggunakan Gson tahu bahawa mereka perlu mentakrifkan jenis TypeToken semasa penyahserilan Suka ini
private Type type = new TypeToken<List<Map<String, Foo>>>(){}.getType(); //调用fromJson方法时把type传过去,如果type的类型和json保持一致,则可以反序列化出来 gson.fromJson(json, type);
Tiga soalan
1 Mengapa menggunakan TypeToken untuk mentakrifkan jenis deserialisasi? Seperti yang dinyatakan di atas, jika anda terus melepasi jenis Senarai
2. Mengapakah terdapat pendakap {}? Kurung ini adalah intipatinya. Seperti yang kita sedia maklum, dalam sintaks Java, dalam konteks ini, {} digunakan untuk mentakrifkan kelas tanpa nama ini mewarisi kelas TypeToken, yang merupakan subkelas TypeToken.
3. Mengapakah kita perlu mendapatkan jenis generik melalui subkelas? Ini adalah kunci kepada TypeToken yang boleh mendapatkan jenis generik Ini adalah kaedah yang bijak. Ideanya adalah seperti ini. Memandangkan generik dalam List
Generik kelas induk yang perlu diwarisi oleh subkelas saya telah ditentukan. Sudah tentu, JVM menyimpan bahagian maklumat ini dan ia disimpan dalam maklumat Kelas subkelas.
Jadi bagaimana kita boleh mendapatkan maklumat ini? Nasib baik, Java menyediakan API:
Type mySuperClass = foo.getClass().getGenericSuperclass(); Type type = ((ParameterizedType)mySuperClass).getActualTypeArguments()[0]; System.out.println(type);
Ringkasnya, untuk kelas dengan generik, objek ParameterizedType dikembalikan, untuk Objek, antara muka dan jenis primitif, null dikembalikan, dan untuk kelas tatasusunan, Objek dikembalikan. kelas. ParameterizedType ialah jenis Java yang mewakili jenis dengan parameter generik Selepas pengenalan generik dalam JDK1.5, semua Kelas dalam Java melaksanakan antara muka Type ParameterizedType mewarisi antara muka Jenis Semua kelas yang mengandungi antara muka ini.
Nyahpepijat sendiri dan anda akan tahu apa yang ia kembalikan.
Prinsip
Kaedah teras ialah dua ayat yang disebut tadi, dan selebihnya sangat mudah. Mari lihat kaedah getType TypeToken
public final Type getType() { //直接返回type return type; }
Lihat pada permulaan jenis
//注意这里用了protected关键字,限制了只有子类才能访问 protected TypeToken() { this.type = getSuperclassTypeParameter(getClass()); this.rawType = (Class<? super T>) $Gson$Types.getRawType(type); this.hashCode = type.hashCode(); } //getSuperclassTypeParameter方法 //这几句就是上面的说到 static Type getSuperclassTypeParameter(Class<?> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; //这里注意一下,返回的是Gson自定义的,在$Gson$Types里面定义的TypeImpl等,这个类都是继承Type的。 return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); }
Atas ialah kandungan terperinci Cara menggunakan TypeToken dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!