2017-06-25 120 views
5

Java'daki wrapper sınıfının neden bir referans türü gibi davranmadığını anlamak için çok büyük bir sorunum var. Örnek:Java'daki sarma sınıfı neden bir referans türü gibi davranmıyor?

Integer one = 10; 
Integer two = one; 
one = 20; 
System.out.println(one); 
System.out.println(two); 

çıkışı olacaktır:

:

Ben two Kendi sınıf oluşturmak, bu örnekte olduğu gibi 20 olacağı düşünülmektedir

class OwnInteger { 
     private int integer; 

     public OwnInteger(int integer) { 
      this.integer = integer; 
     } 

     public int getInteger() { 
      return integer; 
     } 

     public void setInteger(int integer) { 
      this.integer = integer; 
     } 
    } 

    OwnInteger one = new OwnInteger(10); 
    OwnInteger two = one; 
    one.setInteger(20); 
    System.out.println(one.getInteger()); 
    System.out.println(two.getInteger()); 

Soru, Integer sarmasıdır özel sınıf özel mi? Örneklerimde gösterdiğim gibi neden davranıyor?

+4

One = 20; 've' one.setInteger (20); 'arasında büyük bir fark vardır ve sarıcı sınıfları ile ilgisi yoktur. İlk snippet'in bir = 20; 'si, ikinci snippet'te bir = yeni OwnInteger (20); – Eran

+1

Bu sınıflar, muhtemelen _are_ referans türleri oldukları için referans türleri gibi davranırlar. Bir referansı farklı bir nesneye işaret ettiğinizde, diğer işaretçiyi değiştirmezsiniz. İşaretçiler bağımsızdır. Sadece _object_ ile aynı _object_ işaretçileri tarafından görülebilen değişiklikler. JLS'nin dediği gibi, Java'nın "referansları ... işaretçiler" olduğunu unutmayın. –

cevap

8

eşit olacaktır .. aynı referans işaret ediyor beklediğim yapmak yazın. Örneğinizde, two, atamadan sonra one ile aynı nesneyi başvuruyor. Ancak, one'un yeniden atanması yeni bir nesnenin two üzerinde bir etkisi yoktur, gördüğünüz davranış budur.

için bir amacı, diğer değişiklikleri değişen davranış sergilemek için bir referans sınıfı için örnek

StringBuilder one = new StringBuilder("10"); 
StringBuilder two = one; 
one = new StringBuilder("20"); 
// two still references StringBuilder with "10" 

için, hem de diğer referans nesneleri ile aynı davranış görür

, sınıf olması gerekir mutable, kodunuzdaki OwnInteger sınıfındaki gibi, ve kodu yeniden atamak yerine nesneyi değiştirmeniz gerekir. Integer gibi Sarıcı sınıfları değişmezdir, dolayısıyla bu davranışları onlarla yaşamayacaksınız. davanız valueOf yöntemde

one = Integer.valueOf(20); 

yeni bir nesne oluşturmak ve daha önce önbellekte bulunmayan çünkü yeni oluşturulan nesnenin bir başvuru döndürmek:

3

Ben size aslında değişken one ve değişkene Yeni bir nesne atayarak bu

Integer two = one; 
one = 20; 

yaptığınızda iki 20 ...

nop, olacağı düşünülmektedir two bu değişiklikler hakkında herhangi bir bilgi sahibi olamaz ...

yourInteg er

OwnInteger one = new OwnInteger(10); 
OwnInteger two = one; 
one.setInteger(20); 

onlar Bu tam bir referans davranıştır çünkü one ve two

kod A

OwnInteger one = new OwnInteger(10); 
OwnInteger two = one; 
one = new OwnInteger(20); //one.setInteger(20); 
+0

"bir ve iki aynı başvuruya işaret ediyor." Yanlış, aynı _object_ işaret ediyorlar. –

0
one = 20; 

"boks" kullanarak ve bu aslında eşdeğerdir .

Kendi sınıfınız için one ve two her iki referans değişkeni de aynı nesneyi işaret eder.

+0

Aynı şey, otomatik gözlem olmadan bile gerçekleşmişti, bu OP'nin gözleminin sebebi de değil. –

0

Şimdiye kadarki diğer cevaplar en azından kısmen yanlıştır. Gördüğünüz efektin otomatik kutulama veya mutabilite ile ilgisi yoktur. İlk adımınız gibi bir işaretçiyi değiştirmek ve bir nesneyi ikinci adımdaki gibi bir işaretçi ile değiştirmek tamamen farklı şeylerdir. İşaretçiyi değiştirmek onu farklı bir nesneye işaret etti. Her iki göstergeyi de değiştirmediniz, böylece farklı nesnelere işaret ettiler. Bu, mutabilite veya boks dönüşümden bağımsız olarak gerçekleşir.