2009-11-16 214 views
1

在Java中使用引用時的注意事項是什麼?在Java中使用引用時的注意事項和注意事項

+4

你是什麼意思的「使用參考」? – 2009-11-16 09:22:07

+0

請在Java上下文中添加一個示例(代碼片段),以幫助理解您的問題:) – 2009-11-16 09:23:02

+0

@Andreas,我只想解決在Java中使用引用時可能出現的問題。 Not code specfific – 2009-11-16 09:39:50

回答

2

如果你指的是SoftReference的,WeakReference的和PhantomReferences:

DOS:

  • 使用於處於創建或內存明智昂貴的緩存對象的軟引用。這會讓您的應用程序有機會在耗盡內存之前刪除對象,但會降低性能。

  • 如果您需要持有對註冊您的Observer的類的引用,則在使用Observer模式時使用WeakReferences。這保證了監聽器不會阻止父進程被垃圾回收。

注意事項:

軟弱引用的對象可以隨時被刪除,所以不會做:

if (reference.get() != null){ 
    Object o = reference.get(); 
    // Do something with o.... 
} 

這可能是Ø收到一個空指針的情況下,因爲當垃圾收集器將被激活時不能保證。

1

簡而言之...

Java通過引用操縱對象,並且所有對象變量都是引用。但是,Java不會通過引用傳遞方法參數;它通過價值傳遞它們。

所以對象可以通過引用傳遞給方法,但是原始類型(int/boolean)是通過值傳遞的。

此網站解釋differnces一個良好的工作... Javaworld: pass by reference

10

常見的問題,人們誰是新到Java與理解引用:

  • 混淆Java的參數傳球機制。他們認爲,因爲對象是引用,它們在方法調用中「通過引用傳遞」。這不是真的。 Java中的參數總是「按值傳遞」。

  • 關於Java數組是什麼的混淆。數組只是一種特殊的對象。它們是在堆上創建的,具有引用,並且這些引用是「按值傳遞」的......就像任何其他對象一樣。

  • 關於什麼==意味着引用的困惑。它的意思是「與對象相同」,不是「等於」。 equals方法用於測試兩個對象是否相等......無論如何。

  • 新用戶經常出錯的一個衆所周知的子情況是在處理字符串時,兩個字符串對象通常是「相等的」而不是「同一個對象」。簡單的規則是不要使用==來比較字符串

  • 一個不太爲人熟知的子類是基本包裝類Boolean,Character,Integer等。問題......和解決方案......基本上與字符串相同;即不要使用==來比較Boolean,Character,Integer等的實例。

  • 有人遇到問題null。基本概念很簡單,但有些人在拋出異常時會遇到返回null的壞習慣。這會導致大量不必要的測試null和flankiness由於意外NullPointerExceptions當一個必要的空測試被遺漏。

  • 有些人認爲你應該能夠爲堆棧上分配的某個對象創建一個引用。 Java不允許這樣做。在Java中,對象始終分配在堆中。堆棧幀只包含引用和原始值,而Java不提供「取」任何地址的方法。

  • 有些人認爲你應該能夠用引用做指針運算。 Java不允許這樣做。

但基本上,Java的引用是非常簡單的,易於理解,並在很大程度上無故障......一旦你停止努力去想他們在C/C++指針條款。

+0

Stephen,一個很好的答案,但是一個問題:你在這裏指的是通過創建一個對堆棧上創建的對象的引用?我對Java堆棧變量的理解是它們基本上像C,C++等那樣:這就是你的局部變量被創建的地方。當然,我可以爲其中的一個創建一個引用,甚至將它返回給調用者,或將其分配給更廣泛的範圍內的某個東西。所以我不明白你在這裏指的是什麼。你可以解釋嗎? – CPerkins 2009-11-16 11:44:50

+0

@Stephen C:我仍然對Java的參數傳遞感到困惑,我總是通過如果我將巨大的數組/數組列表傳遞給一個函數只傳遞參考,並且該函數現在可以修改原始數組。它是以這種方式工作嗎? – 2009-11-16 16:59:12

+0

@CPerkins:您無法在Java中創建對本地變量的引用。你可以_copy_局部變量的值(可能是引用類型,因此該值將是一個引用)並返回它,但它不是一回事。在C++中,你可以直接在堆棧上創建一個對象,並且有一個指針/引用 - 而不是Java。 – 2009-11-16 21:49:24

0

大多數在這方面的書籍,文章,甚至是你的測試程序可能會給你不好理解像(基本類型總是按值傳遞,而對象和數組總是按引用傳遞) ,如果你想這使用如下基本測試代碼

public class Test {  
     public void changeArrayValues(String[] names) { 
      for(int i=0; i<names.length; i++) 
       names[i] += "_ALTERED"; 
     } 

     public static void main(String[] args) { 
      String[] names = {"Cairo", "Alex", "Giza"}; 
      for(int i=0; i<names.length; i++) 
       System.out.print(names[i] + ", "); 
      System.out.println(); 
      new Test().changeArrayValues(names); 
      for(int i=0; i<names.length; i++) 
       System.out.print(names[i] + ", "); 
     } 
    } 

,你會得到下面的輸出:

開羅,亞歷克斯,吉薩,Cairo_ALTERED,

Alex_ALTERED,Giza_AlTERED

這將強制您的想法進入你的腦海。

(原始類型總是按值傳遞,而對象和數組總是通過引用傳遞)是正確的。因爲按引用傳遞,你可以移動參考指向另一個對象,但在Java中,如果你這樣做了引用的對象不會與變化感到

試試這個

public class Test {  

    public void reIntializeArray(String[] names) { 
     names = new String[]{"X", "Y", "Z"}; 
    } 

    public static void main(String[] args) { 
     String[] names = {"Cairo", "Alex", "Giza"}; 
     for(int i=0; i<names.length; i++) 
      System.out.print(names[i] + ", "); 
     System.out.println(); 
     new Test().reIntializeArray(names); 
     for(int i=0; i<names.length; i++) 
      System.out.print(names[i] + ", "); 
    } 
} 

,這將轉儲以下輸出:

開羅,亞歷克斯,吉薩,

開羅,亞歷克斯,吉薩,

因此,您從輸出中看到數組沒有使用新值進行初始化。

所以在Java中所有通是由值

但是你可以受益於通 - 第一行爲 - 在改變對象的內容,但你必須記住,這就是Java,而不是C++。