2013-12-12 52 views
0

我有兩個類使用相同的String值,並將它們存儲爲最終的專用字段。Java如何處理跨實例的最終字段?

public class Foo{ 
    private final String str; 
    private final Bar bar; //notice this 

    public Foo(String in){ 
     this.str=in; 
     this.bar=new Bar(in);  //option 1 
     this.bar=new Bar(this.str); //option 2 
    } 
} 

這裏來Bar

public class Bar{ 
    private final String boo; 

    public Bar(String in){ 
     this.boo=in; 
    } 
} 
  • 不Java軟件商店相同的對象無處不在,或者它做一個拷貝給每個實例*
  • 對於選項1和2,您的答案是否相同?

* 直覺暗示在前者,但你永遠無法確定與Java。

方問題:
我想要做的是這樣的:Foo確實對str一些處理,並使用Bar作爲一個工具類。概念上Foostr緊密連接在一起,但除構造函數外,Foo不直接再次觸摸str,而只通過Bar

我想過從Foo的字段中刪除str,因爲擔心Java會分配兩次相同的字符串,這引發了這個問題。但是從軟件工程/代碼正確性的角度來看,我應該刪除它嗎?

+3

_但是你永遠無法確定與Java._ Java語言規範是非常清晰的,如果你閱讀它。 –

+3

'final'與被引用的實際對象無關。它僅限制變量。 –

+0

我認爲'final'在編譯時被視爲與C的'const'相同。我想錯了。我可以閱讀[整個規格](http://docs.oracle.com/javase/specs/)...或作爲一個問題在這裏;) – rath

回答

1

由於您沒有實例化另一個String實例,因此您的選項都是相同的引用(在此示例中)。考慮到你的初始調用,我們可以強制它們具有不同的參考值(我不知道你爲什麼要這樣做,並且有後果 - 即增長實習生高速緩存)。

this.str=in; 
this.bar=new Bar(in);      // option 1 
this.bar=new Bar(this.str);    // option 2 

這將改變引用。

this.str = new String(in);    // <-- create a new String from in. 
this.bar = new Bar(in);     // <-- keeps the original reference to in. 
StringBuilder sb = new StringBuilder(in); // <-- create a StringBuilder. 
this.bar = new Bar(sb.toString());  // <-- create another String. 
+0

謝謝。你能舉個例子說明兩者會不一樣嗎? *編輯:*想一想,反例是顯而易見的。乾杯 – rath

+1

@rath:如果你已經完成了'this.str = new String(in);'。 –