2012-03-15 6 views
3

чем разница (память-накрест) междуJVM строки, хранящиеся в памяти

private static final String FAILURE_MESSAGE= "..."; 

protected String getFailedMsg() { 
    return FAILURE_MESSAGE; 
} 

И

protected String getFailedMsg() { 
    return "..."; 
} 

Предполагая, что FAILURE_MESSAGE только ссылки из приведенной выше функции.

Я имею в виду, где и как хранятся вышеуказанные объекты/строки в памяти в вышеуказанных случаях? Является ли это JVM конкретным?

Редактировать: Я знаю, что строка интернирована в первом подходе, но где это значение сохраняется/удерживается/(интернировано?) Во втором подходе до вызова функции?

Second edit as afterthought - что, если строки заменены на int или какой-либо другой класс, который не является строкой?

+0

Вы хотите вернуть {START_MESSAGE}? Вы вернули {FAILURE_MESSAGE}. – sgowd

+0

@ sans481 - спасибо, глупая ошибка копирования папок ... – Vic

+0

Стоит отметить, что все вы, литералы String '' ... "' будут ссылаться на один и тот же экземпляр в памяти. – Kamran

ответ

1

Байткод генерироваться одинаковы в обоих случаях:

protected java.lang.String getFailedMsg() 
    0 ldc 2 (java.lang.String) "..." 
    2 areturn 

так что это чисто сахар.

1

Строковые литералы относятся к тому же объекту String, поэтому в этом случае нет разницы в памяти.

Раздел 3.10.5 Строковые литералы из языка Java Specification 3.0 состояний:

Строковый литерал всегда ссылается на тот же экземпляр (§4.3.1) класса String, ... [ они] являются «интернированы», чтобы обмениваться уникальными экземплярами, используя метод String.intern.

1

Все строковые литералы будут интернированы, поэтому это не имеет никакого значения (по памяти, глядя на пример String).

Единственное отличие состоит в том, что в вашем первом случае класс содержит один ссылочный указатель на экземпляр String. Второй подход создает ссылку только на стек.

+0

Но где значение строки, хранящееся ** до **, создается в стеке во втором подходе? – Vic

+1

@Vic: значение никогда не создается в стеке (только ссылка). Все объекты Java создаются в куче (ну, некоторые современные JVM создают непродолжительные объекты в куче, но здесь это не актуально). –

+0

Вторая часть вашего комментария «единственная разница» .. не прав. В обоих случаях байт-код, созданный для метода, это «LDC », затем «areturn». –

4

Первый пример не компилируется, а второй пример.

Производительность обычно менее важна, чем простота и ясность, и здесь у вас есть хороший пример. Если он скомпилирован, первый пример будет таким же быстрым, как второй.

BTW: Не имеет значения, сколько раз и сколько классов используется строковый литерал, все они будут String.intern(), поэтому все они будут одним и тем же объектом.

+1

:-P (good catch;)) –

+0

Извините, что это была ошибка копирования, но вопрос все еще сохраняется. – Vic

+0

Он также подтверждает мою точку зрения о том, что проще быть лучше. ;) –

0

В обоих случаях он создает литерал в пуле строк. После создания String s = "...", если u попытается вернуть «...» в любом методе, оба указывают на один строковый литерал, созданный в пуле строк.

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