6 Eylül 2020 Pazar

Autoboxing

Giriş
Referans tip beklenen kodda primitive kullanırsak, derleyici tarafından arka planda bir çevrim gerçekleşir. Bu çevrime Autoboxing denilir. Bu özellik Java 1.5 ile geliyor.  Yani çok eskiden beri var. Açıklaması şöyle
However, version 1.5 of the JDK introduced the autoboxing of Java primitive types. This means the wrapper class will get created automatically when a primitive type is used anywhere a reference type is expected.
Eski Kodlar
Java 5'ten önce şöyle yapılırdı.
int x = 10;
ArrayList<E> list = new ArrayList();
// list.add(10); Pre JDK 1.5 autoboxing would not work
Integer wrapper = Integer.valueOf(x);
list.add(wrapper);
Autoboxing Nasıl Çalışır?
Autoboxing işleminde derleyici bizim için Integer.valueOf() gibi bir metodu otomatik olarak çağırır. 

Üretilen kod şöyledir
// Example of auto-boxing, here c is a reference type
Integer c = 128; // Compiler converts this line to Integer c = Integer.valueOf(128); 
// Example of auto-unboxing, here e is a primitive type
int e = c; // Compiler converts this line to int e = c.intValue();

Auto-unboxing Nedir?
Autoboxing işleminin tersine, Auto-unboxing denilir.

Primitive Tipler
Java'da 8 tane primitive tip var. Bunlar şöyle
byte, short, int, long, float, double, char, ve boolean
int Tipi
Autoboxing işlemin tuhaf bir yan etkisi olabiliyor. Açıklaması şöyle. Bu da JVM'in alt tarafta bir Integer cache kullanmasından kaynaklanıyor. Bu cache integer tipi için -128 to 127 değerleri arasında
In an interview, one of my friends was asked: If we have two Integer objects, Integer a = 127; Integer b = 127; Why does a == b evaluate to true when both are holding two separate objects
Açıklaması şöyle
... direct assignment of an int literal to an Integer reference is an example of auto-boxing concept where the literal value to object conversion code is handled by the compiler, so during compilation phase compiler converts Integer a = 127; to Integer a = Integer.valueOf(127);.
Integer.valueOf()  metodunun içi şöyle
 public static Integer valueOf(int i) {
  if (i >= IntegerCache.low && i <= IntegerCache.high)
    return IntegerCache.cache[i + (-IntegerCache.low)];
  return new Integer(i);
 }
long Tipi
long primitive tipi nedense Byte referans tipine çevrilemiyor. Şu kod derlenmez.
final int i = 3;
Byte b = i; // no error

final short s = 3;
Byte b = s; // no error


final long l = 3;
Byte b = l; // error
Şu kod derlenmez.
// Both compiler errors.
byte primitive = 0L;
Byte wrapped = 0L;


Hiç yorum yok:

Yorum Gönder