24 Eylül 2020 Perşembe

Generics ve Bounded Wildcard Denkliği

Giriş
1. Aynı şekilde tanımlanmış iki tane Generics + Bounded Wildcard denk değildir
2. Wildcard olmase bile aralarında kalıtım olan iki tane farklı tipin kullanıldığı generic tipler denk değildir. Örneğin Box<Number> ve Box<Integer> denk değildir.

Açıklaması şöyle.
The usage of two bounded wildcards with the same bound doesn't mean they are the same type.
Bir başka açıklama şöyle. Yani her extends vs kullanımı aynı ata tipi kullansa daha farklı şeyler olarak algılanır.
First of all, every single wildcard is captured, everywhere, by javac. In plain english: every time javac "sees" a wildcard it is going to transform that
Örnek
Şu kod derlenmez
void test(List<? extends Number> g1, List<? extends Number> g2) {
    g1 = g2;
}
Bu kod java açısında şunun aynıdır. X1 ve X2 birbirleriyle ilgisiz tiplerdir ve iki liste birbirine atanamazlar.
void test(List<X1>, List<X2>)
Örnek
Elimizde şöyle bir kod olsun
void  persistData(ActivityDao<? extends BaseActivity> activityDao,
                  Collection<? extends BaseActivity> data){
  ...
  activityDao.saveAll(data);
  ...  
}
Bu metod derleyici tarafından şöyle algılanır. Haliyle derlenmez
private void  persistData(ActivityDao<CAP#1-of-? extends BaseActivity> activityDao,
                         Collection<CAP#2-of-? extends BaseActivity> data){
  ...
  activityDao.saveAll(data);
  ...
}
Bunu düzeltmenin tek yolu şöyle. Burada extends kullanımı kaldırılıyor!
private <T extends BaseActivity> void  persistData(ActivityDao<T> activityDao,
                                                   Collection<T> col){
  ...
  activityDao.saveAll(col);
  ...
}
Örnek
İki listeyi birleştirmek için şöyle yaparız. Burda metod imzasında extends var ancak içeride yeni bir liste yaratılıyor.
List<Foo> collect( List<? extends Foo> a1, List<? extends Foo> a2 )
{
  List<Foo> collected = new ArrayList<>();
  collected.addAll( a1 );
  collected.addAll( a2 );
  return collected;
}
Şöyle yapsaydık kod derlenmezdi.
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
Şuna benzer bir bir hata alırız.
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)

no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)


Hiç yorum yok:

Yorum Gönder