2016-02-01 9 views
6

Oracle tarafından resmi Java öğreticisinden alınmış, bkz. question 2 here (bana göre).Bir String nesnesine dizi öğesi ayarlarken, öğe nesneyi referans alır mı?

public static void main(String[] args) { 

    String[] students = new String[10]; 
    String studentName = "Peter Smith"; 
    students[0] = studentName; 
    studentName = null; 

    System.out.println(students[0]); 

} 

cevap dizisi students hala başvuran beri studentName çöp toplama için uygun olmadığını söylüyor. Ancak, son satır "Peter Smith" yazdırır, bana göre students[0]studentName referansı yanlış görünüyor. Birisi bunu açıklayabilir mi?

+2

Birşeyi yazdırmanın referans olup olmadığını etkilediğini mi düşünüyorsunuz? Eğer öğrenciler [0] '*“ studentName ”a atanan dizgeye başvurmadıysa, nasıl yazdırılır? –

+0

Başka ne referans olurdu? – ChiefTwoPencils

+3

'öğrencileri [0] = studentName'' studentName' değişkeni için bir başvuru yaratıyor, '' dır. – Taelsin

cevap

5

Referans değişkenleri (studentName ve students[0]) başvuru yaptıkları nesne ("Peter Smith") ile karıştırıyorsunuz. studentName ve students[0] her ikisi de "Peter Smith" String nesnesine başvurur. Bir kez bunlardan hiçbiri "Peter Smith" referansı - ve başka yerde başka bir referans olmadığını varsayarak - bu nesne çöp toplama için uygun olacaktır. Referanslar kendilerini kapsam dışında kaldıklarında gider.

Öğretici yanlış anladı. studentName numaralı bir nesne yok. studentName, bir noktada, "Peter Smith" referansını tutan ve başka bir noktada null olan bir değişkendir. Benzer şekilde, students[0], "Peter Smith" (aynı String nesnesi) referansını içeren bir bellek konum dizisinde bir öğedir. Öğretici, değişkenler fikrini, referans verdikleri nesnelerle karıştırır.

Bellek kullanım ayrıntılarına girmemek için bunu yaptıklarını tahmin edebilirim. Bu gelişmiş bir konu. Fakat açıklama IMO'ları önlediğinden daha fazla karışıklığa neden oluyor.

+1

Gerçekten bunu yanlış anladım. Bununla birlikte, öğretici cevapta "ÖğrenciAdı" nesnesi uygun değil, çünkü öğrenciler [0] 'yine de buna atıfta bulunuyor. Ama bu yanlış değil mi? Öğrenciler [0], "Peter Smith" dizesine değil, studentName 'dizgesine işaret ediyor mu? Öğretici cevap, bunu da karıştırıyor gibi görünüyor. – cmeeren

+0

Kafan karıştığın için seni suçlamıyorum. Bu sorunun cevabı (Oracle öğreticisi # 2) zayıf bir şekilde ifade edildi. –

+0

Yorumumu düzenledim, hala karışık, üzgünüm – cmeeren

7

Adım adım diyagramların yardımıyla açıklamak isterim.

String studentName = "Peter Smith"; 

ilk satırdan sonra bir dize dize havuzu ve studentName ona doğru işaret referans adıyla oluşturulur. Aşağıdaki şemada gösterildiği gibi, bu noktada

students[0] = studentName; 

Part1

, başka bir referans öğrenci [0], aynı nesneye işaret. Şimdi 2 referans hafızada oluşturulan aynı nesneyi işaret ediyor.

studentName = null; 

Part2 Bu noktadan sonra, studentName referans hiçbir nesneye işaret, yani boş işaret edecektir. Ancak öğrencilerin [0] referansı, oluşturulan String nesnesine (Peter Smith) işaret ediyor.

enter image description here

Açıkça üçüncü deyimi sonra, bir referans null işaret ama bir referans hala oluşturulan Nesne işaret ediyor. Bu nedenle, nesne çöp toplama için uygun değildir.

Yardım edin.

Güncelleştirme: Üzgünüz, değişken adlarını karıştırdım. Ama umarım fikrini alırsın.

+0

Teşekkürler, harika cevap! Bunu takdir ediyorum. Erick'in cevabı belliydi (ve öğreticideki ifadelere ilişkin bazı karışıklıklardan kurtuldu), ama ben de bunu geri çekiyorum. – cmeeren

+0

@cmeeren: Sevindim, yardım edebilirim :) :) – thedarkpassenger

1

olarak bildiğim kadarıyla, kod aşağıdaki gibi çalışır:

  1. String[] students = new String[10]; - students dizi oluşturun. students değişkeni artık bellekteki nesnenin bir göstericisidir.
  2. String studentName = "Peter Smith"; - studentName değişkenini işaretçiyi "Peter Smith" değerine atayın. studentName değişken aslında ad değerini içermiyor.
  3. students[0] = studentName; - Dizideki ilk öğeyi işaretçiyi "Peter Smith" değerine atayın. Bu noktada hem studentName ve students[0] At

aynı şey işaret ediyor, ama ikisi de değerini kendisi içerirler.

  1. studentName = null; - Bu null başvuru belirler. Altta yatan bellek ayırmayı temizlemez.
  2. System.out.println(students[0]); - Peter Smith yazdıracaktır. Dizideki 0 öğesi, özgün dize nesnesine bir işaretçi içerir. Orijinal işaretçi (studentName) null ayarlanmış olsa bile

dizisi hala "Peter Smith" nesnesine bir başvuru içerdiğinden, nesne çöp toplama için uygun olmaz. Java değerlerini ve işaretçileri işleme biçimi hakkında biraz daha okumak istiyorsanız


bu mesajlar yardımcı olabilir:

1

bir olduğunu düşünün içinde "Peter Smith" bulunan bir bellek alanını işaret eden nesne. Bu nesneye atanan başka bir nesne de, bu ikinci nesne de bu bellek hücresini işaret ediyor. Bundan sonra birisi herhangi bir bellek hücresini işaret etmemek için ilk nesneyi istiyor, ancak ikincisi hala içinde hala "Peter Smith" değerine sahip olan aynı hücreye işaret ediyor, bu yüzden son satır adı yazdırıyor. Sanırım jvm, yine de değeri olduğu için ilk nesneyi silemediğini, ikinci nesnenin bir başkasının hala onu kullandığını gösteren bir işaretçiye sahip olmamasına rağmen açık olduğunu sanıyorum (sanki bir tanesi bir adresi işaret ediyorsa değil)) hala başka biri tarafından kullanılıyor

İlgili konular