Giriş
Type erasure kod derlendikten sonra generic parametrenin tipinin kaybedilip başka bir şey haline gelmesidir. Açıklaması şöyle. Tipin kaybedilmemesi kavramı Reified Generics. Bu kavram şu anda Java'da yok
Örnek
Elimizde şöyle bir kod olsun.
Elimizde şöyle bir kod olsun. stringList generic olmadığı için farklı tipte nesneler eklenebiliyor.
m1 metodu Iterator<Object> haline geldiği için System.out.println(Object) metodunu çağırır ve sorun çıkmaz.
Ancak m2() metodu ClassCastException fırlatır. Çünkü Iterator<Object> haline gelse bile System.out.println(String) metodunu çağırır ve exception alırız.
Şu kod type erasure yüzünden derlenmez. Aslında amaç bazı Class tipinin kodlanmamasını sağlamak.
Çözüm
Düzeltmek için şöyle yaparız.
Şöyle yaparız. Böylece sadece MyInterface'ten kalıtan sınıflar derlenebilir.
Type erasure kod derlendikten sonra generic parametrenin tipinin kaybedilip başka bir şey haline gelmesidir. Açıklaması şöyle. Tipin kaybedilmemesi kavramı Reified Generics. Bu kavram şu anda Java'da yok
On runtime there are no type checkings in collections
Örnek
Elimizde şöyle bir kod olsun.
public static <T> T handle(T val) {
System.out.println("T");
return val;
}
public static <T extends String> T handle(T val) {
System.out.println("T extends String");
return val;
}
Kod derlendikten sonra şu hale gelir.public static Object handle(Object val) {
System.out.println("T");
return val;
}
public static String handle(String val) {
System.out.println("T extends String");
return val;
}
Örnek - ClassCastException Elimizde şöyle bir kod olsun. stringList generic olmadığı için farklı tipte nesneler eklenebiliyor.
m1 metodu Iterator<Object> haline geldiği için System.out.println(Object) metodunu çağırır ve sorun çıkmaz.
Ancak m2() metodu ClassCastException fırlatır. Çünkü Iterator<Object> haline gelse bile System.out.println(String) metodunu çağırır ve exception alırız.
public static void main(String[] args) {
ArrayList stringList = new ArrayList();
stringList.add(new Employee(1,"A"));
stringList.add(new Employee(2,"j"));
stringList.add(new Employee(3,"d"));
stringList.add("Hello");
stringList.add(new String("Abc"));
stringList.add(10);
stringList.add(new Integer(100));
System.out.println(stringList);
m1(stringList);
m2(stringList);
}
public static void m1(ArrayList<Employee> al){
Iterator<Employee> iterator = al.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
public static void m2(ArrayList<String> al){
Iterator<String> iterator = al.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
Örnek - Derleme HatasıŞu kod type erasure yüzünden derlenmez. Aslında amaç bazı Class tipinin kodlanmamasını sağlamak.
public class Publisher<T> {
private static final Class[] SUPPORTED_CLASSES = new Class[]{T1.class, T2.class};
public Publisher() {
if(Arrays.asList(SUPPORTED_CLASSES).contains(T)) { // error: expression expected!
System.out.println("Class not supported!");
}
}
}
Çünkü T'nin tipi çalışma esnasında yoktur. Yaninew Publisher<T1>
ilenew Publisher<T2>
arasındaki farkı kaybederiz.Çözüm
Düzeltmek için şöyle yaparız.
public Publisher(Class<T> clazz) {
if(!SUPPORTED_CLASSES.contains(clazz)) {
System.out.println("Class not supported!");
}
}
Çözüm
Şöyle yaparız. Böylece sadece MyInterface'ten kalıtan sınıflar derlenebilir.
public class Publisher<T extends S, MyInterface>
Hiç yorum yok:
Yorum Gönder