2013-12-12 2 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 как утилита класса. Концептуально Foo и str тесно связаны друг с другом, но кроме конструктора Foo не касается непосредственно str, но только через Bar.

Я думал об удалении str из полей Foo, опасаясь, что Java дважды выделяет одну и ту же строку, что вызвало этот вопрос. Но с точки зрения правильности программного обеспечения и правильности кода я должен удалить его?

+3

_but вы никогда не можете быть уверены в Java._ Спецификация языка Java предельно ясна, если вы его прочитали. –

+3

Также 'final' не имеет ничего общего с фактическим объектом, на который делается ссылка. Он ограничивает только переменную. –

+0

Я думал, что 'final' обрабатывается так же, как' '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

Спасибо. Не могли бы вы привести мне пример, где они были бы разными? * Редактировать: * Просто подумал об этом, и контр-пример очевиден. Cheers – rath

+1

@rath: Если вы сделали 'this.str = new String (in);'. –

Смежные вопросы