1. Referans değişkenler
Java dilinde iki tür değişken vardır: ilkel değişkenler ve diğer her şey. Olduğu gibi, şimdi "geri kalan her şey" hakkında konuşacağız.
Aslında ilkel değişkenler ve referans değişkenler var demek daha doğru olur . Peki nedir bu referans değişkenler?
Değişkenleri doğrudan değerleri depolayan ilkel türlerin aksine, başvuru değişkenleri nesnelere yapılan başvuruları depolar. Yani, bellekte bir yerde bir nesne vardır ve referans değişkeni basitçe bu nesnenin adresini bellekte saklar (nesneye bir referans).
Yalnızca ilkel türler, değerleri doğrudan değişkenlerin içinde depolar. Diğer tüm türler yalnızca bir nesne başvurusunu saklar . Bu arada, zaten iki tür değişkenle karşılaştınız - String
değişkenler ve dizi değişkenleri.
Hem bir dizi hem de bir dize, bellekte bir yerde depolanan nesnelerdir. String
değişkenler ve dizi değişkenleri yalnızca nesnelere yapılan başvuruları depolar.
int a, int b and double d
değerlerini kendi içlerinde saklayan ilkel değişkenlerdir.
Değişken bir String str
referanstır ve adresi (referans) bir String
nesneye bellekte saklar.
İlkel türdeki bir değişkene ilkel bir değer atarken, değeri kopyalanır (çoğaltılır). Bir referans değişkeni atanırken, yalnızca nesnenin adresi kopyalanır - nesnenin kendisi kopyalanmaz .
2. Referanslar ne hakkındadır?
Referans değişkenler ile ilkel değişkenler arasındaki temel fark nedir?
İlkel bir değişken bir kutu gibidir: içinde bir miktar değer saklayabilirsiniz. Bir referans değişkeni, üzerinde telefon numarası bulunan bir kağıt parçası gibidir.
Bir araba vs arabanın anahtarları
Arkadaşınıza doğum günü için bir araba vermeye karar verdiğinizi hayal edin. Bir kutuya sarıp yanınızda taşımayacaksınız: araba bunun için çok büyük.
Sadece araba anahtarlarını içine alacak kadar büyük bir kutuda sunmak çok daha uygundur. Arkadaşınız anahtarları kutudan çıkardığında her şeyi anlayacaktır. Anahtarları kolayca teslim edebileceğiniz zaman tüm arabayı yanınızda taşımanıza gerek kalmaz.
Bir kişi ve onun telefon numarası
Veya işte başka bir karşılaştırma: bir kişi ve onun telefon numarası. Telefon numarası kişi değildir, ancak telefon numarası onu aramak, ondan bilgi istemek veya talimat vermek için kullanılabilir.
Benzer şekilde, bir nesneyle etkileşim kurmak için bir referans kullanılır. Tüm nesneler, referansları kullanarak birbirleriyle etkileşime girer. "Kişileri değiş tokuş etmek" yerine, sadece telefon numaralarını değiş tokuş ediyoruz.
İlkel bir değişkene bir değer atarken, değeri kopyalanır (çoğaltılır). Bir referans değişkene bir değer atarken, sadece nesnenin adresi (telefon numarası) kopyalanır - nesnenin kendisi kopyalanmaz.
Bir referans bir avantaj daha sunar: bir nesne referansını bir yönteme iletebilirsiniz ve yöntem, nesneye yapılan başvuruyu kullanarak, yöntemlerini çağırarak ve nesnenin içindeki verilere erişerek nesneyi değiştirebilir (değiştirebilir).
3. Referans atama
Referans değişkenleri atanırken, yalnızca nesnenin bellekteki adresi atanır. Nesnelerin kendileri görünmez veya kaybolmaz.
Bu yaklaşım, büyük miktarda belleğin kopyalanmasını önler. Bir metoda çok büyük bir nesne iletmeniz gerekirse, biz sadece nesne referansını iletiriz, o kadar. Referans çok daha az yer kaplar.
Tüm referans değişkenlerinin boyutu (türlerinden bağımsız olarak) aynıdır - 4 bayt (int gibi). Ancak! Uygulamanız 64 bit Java makinesinde çalışıyorsa, tüm referansların boyutu 8 bayt (64 bit) olacaktır.
Ayrıca referanslar sadece birbirlerine atanabilir. Referansları değiştiremez veya referans değişkenlerine rasgele değerler atayamazsınız:
kod | Tanım |
---|---|
|
buna izin verilir |
|
Ama buna izin verilmiyor |
|
Ve buna izin verilmiyor |
4. null
Referans
Ve kendisine henüz hiçbir şey atanmamışsa bir referans değişkeni neyi saklar?
Boş bir referans saklar . null
referansın yokluğu (boş bir referans) anlamına gelen özel bir Java anahtar sözcüğüdür. Değer null
herhangi bir referans değişkene atanabilir.
Tüm referans değişkenleri, null
kendilerine bir tür referans atanmış olmadıkça.
Örnekler:
kod | Tanım |
---|---|
|
Değişkenin String name varsayılan bir değeri vardır: null . Değişkenin int age varsayılan bir değeri vardır: 0 . |
Bir değer atanmamış yerel değişkenler, hem ilkel hem de referans türleri için başlatılmamış olarak kabul edilir.
Bir değişken, bir nesneye referans depoluyorsa ve değişkenin değerini silmek istiyorsanız, o zaman ona boş bir referans atayın.
kod | Tanım |
---|---|
|
s mağazalar null _ bir dize nesnesine s bir başvuru saklar .s null |
5. Yöntemlere referansları iletmek
Bir yöntemin referans türleri olan parametreleri varsa , değerler yönteme referans olmayan değişkenlerle çalışırken olduğu gibi iletilir. Parametreye basitçe diğer değişkenin değeri atanır.
Örnek:
kod | Tanım |
---|---|
|
fill Geçen diziyi ( array ) geçen değerle ( ) doldurur value . |
Yöntem fill
çağrıldığında, parametreye array
diziye bir başvuru atanır data
. Değişkene value
, dize nesnesine ("Merhaba") bir başvuru atanır.
Bu, yöntemi çağırmadan önce belleğin nasıl göründüğüdür fill
:
Yöntem fill
çalışırken bellek şöyle görünür :
data
ve değişkenleri array
, bellekteki aynı kapsayıcıya başvurur (referansları depolar).
Değişken value
, string nesnesine ( "Hello"
) bir referans depolar.
Dizinin hücreleri ayrıca yalnızca nesneye yapılan başvuruları saklar "Hello"
.
Aslında, hiçbir nesne kopyalanmaz; yalnızca referanslar kopyalanır.
6. C/C++ dili ile karşılaştırma
Röportajlarda, bazen Java programcılarına verilerin Java'daki yöntemlere nasıl aktarıldığı sorulur. Ve bazen soru, verilerin referansa göre mi yoksa değere göre mi iletildiğidir?
Bu soru C++'dan geliyor, ancak Java'da çok anlamlı değil . Java'da, parametrelere her zaman argümanların değerleri atanır. Yani doğru cevap " değere göre " olacaktır .
Ancak konumunuzu açıklamaya hazırlıklı olun , çünkü hemen şu yanıtı duyabilirsiniz: "ilkel tipler değere göre iletilir ve referans tipler referansa göre iletilir."
Bu sorunun kaynağı, birçok Java programcısının geçmişte C++ programcısı olmasından kaynaklanmaktadır. O programlama dilinde parametrelerin metotlara nasıl aktarıldığı sorusu çok önemliydi.
Java'da her şey açıktır: ilkel türler değerleri depolar ve referans türleri de bir değer - bir referans depolar. Bu, bir değişkenin bir değer olarak kabul edilip edilmediği sorusudur .
C++'da bir değişken, hem bir nesneye hem de nesnenin kendisine yapılan bir başvuruyu depolayabilir. Aynısı ilkel türler için de geçerliydi: İlkel bir değişken, bir değeri saklayabilir veya değişkeni bir int
. Bu nedenle, karışıklığı önlemek için, C++ programcıları her zaman bir başvuruya ilişkin nesneye bir başvuru olarak ve nesnenin kendisine - bir değer olarak atıfta bulunur.
C++'da, bir değişkenin bir nesne içerdiği, ancak diğerinin o nesneye bir başvuru içerdiği bir duruma kolayca sahip olabilirsiniz. Buna göre, bir değişkenin neyi sakladığı sorusu - nesnenin kendisi mi yoksa sadece ona bir referans mı - çok önemliydi. Bir nesne bir yönteme iletildiğinde, kopyalandı (değere göre iletildiyse) ve kopyalanmadı (referans olarak iletildiyse).
Java'da bu ikilik yoktur, dolayısıyla doğru yanıt şudur: bağımsız değişkenler Java yöntemlerine değere göre iletilir . Sadece referans değişkenlerinden bahsederken bu değer bir referanstır.
GO TO FULL VERSION