covariance etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
covariance etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

8 Haziran 2021 Salı

Array İçin Covariant Nesne Atama - Covariance

Giriş 
Açıklaması şöyle. Derleme hatası almasak bile çalışma esnasında exception fırlatılması sıkça görülen bir olay
The main difference between arrays and generics is that arrays are covariant while generics are not. It means that Number[] is a supertype for Integer[]. And Object[] is a supertype for any array (except primitive ones). That seems logical, but it may lead to bugs at runtime.
Örnek
Elimizde şöyle bir kod olsun. Derleme hatası almasak bile farklı tipten bir nesne atamaya kalkarsak ArrayStoreException alırız.
Number[] nums = new Long[3];
nums[0] = 1L;
nums[1] = 2L;
nums[2] = 3L;
Object[] objs = nums;
objs[2] = "ArrayStoreException happens here";
Açıklaması şöyle
This code does compile but it throws an unexpected exception.
Eğer Generic kullansaydık derleme hatası alırdık
List<Number> nums = new ArrayList<>();
List<Long> longs = new ArrayList<>();
nums = longs; // compilation error
Örnek - Kalıtan Tipten Array'a Cast Etme
B tipinden nesne içeren A tipinden dizi, B tipinden diziye cast edilemez. Aslında derleniyor ancak çalışma zamanında exception fırlatır.
Örnek
Elimizde şöyle bir kod olsun.
public static class A { }
public static class B extends A { }

public static void main(String [] args) {
  A[] a = new A[100];
  for (int i = 0; i < a.length; i++) {
    a[i] = new B();
  }
  B[] b = (B[]) a;  /* Error: ClassCastException, even if all elements are of type B */
}

27 Mayıs 2019 Pazartesi

Covariant Nesne Atama - Covariance

Giriş
<? extends Animals> şeklindeki generics bir çok kısıtlama ile geliyor

1.  <? extends Animal> listesi <Animal> listesine cast edilemez
2. <Animal> listesi Dog taşısa bile <Dog> listesine cast edilemez.

Örnek - Ekleme Yapılamaz
Elimizde şöyle bir kod olsun. animals listesine add() ile ekleme yapılamaz.
List<? extends Animal> animals = new ArrayList<Cat>();
//animals.add(new Cat()); // compile error
//animals.add(new Animal()); // compile error
Animal animal = animals.get(0);
Örnek - Ata Tipten Collection'a Cast Etme
Şu kod derlenmez.
List<? extends Animal> foo() {
  List<Dog> dogs = new ArrayList<>();
  return dogs;
}

List<Animal> dogs = foo(); // compile error
Sebebi ise bir kaç katmanlı cast kullanarak atama yapılmasının yanlış olması. Örneğin bu iş olsaydı şu kod hatalı olurdu. Cat listesini Animal listesine cast edip, Animal listesine Dog ekleme mümkün olurdu.
List<Cat> listOfCats = new ArrayList<>();
List<? extends Animal> listOfSomeAnimals = listOfCats;  // Fine.
List<Animal> listOfAnimals = listOfSomeAnimals;  // Error, pretend it works.
listOfAnimals.add(new Dog());