LINUX.ORG.RU

String — это не primitive type

 ,


1

2
String a = "a";
String b = a;
b += 1;

System.out.println(a);

Что должен вывести код? Пишите ваши предположения (код не запускать). Почему именно так?

★★★★★

Последнее исправление: CYB3R (всего исправлений: 1)

Не выдержал и скомпилил. По поводу b — догадывался. По поводу a — немного удивился О_о

Хотя, это всё, может, оттого, что в последнее время я только в крестах...

Deleted
()
Последнее исправление: ecko (всего исправлений: 2)

String хоть и не primitive, но immutable.

CARS ★★★★
()

Выведет a

String a = "a";
//String b = a;
//b += 1;

System.out.println(a);
По сути.

yacuken ★★★★
()

«b» изменится небось, «a» останется как был.

vurdalak ★★★★★
()

Подозреваю, что выведет a. String хоть и не примитивный тип, но неизменяемый, а b += 1 преобразуется компилятором в b = b + 1 (т.е. переменная b будет ссылаться на новый экземпляр класса String).

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)

a

толи вопрос глупый, толи я тупой

update: все таки первое

fornlr ★★★★★
()
Последнее исправление: fornlr (всего исправлений: 1)
Ответ на: комментарий от CARS

Да, уже посмотрел. А в чём дело. Уверен, что с `int` вместо `Integer` всё будет хорошо, но почему происходит то, что происходит?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от Begemoth

b += 1 преобразуется компилятором в b = b + 1 (т.е. переменная b будет ссылаться на новый экземпляр класса String)

Весьма странное понимание иммутабельности.

buddhist ★★★★★
()
Ответ на: комментарий от CYB3R

Ну, хз. Вроде, же. Integer ссылка на объект, int строенный тип.
Для ссылок равно не равно, нужно equals или int.

anonymous
()
Ответ на: комментарий от buddhist

Объекта, а не переменной. Меня после сишных const char* и char * const не удивляет.

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от buddhist

Ещё как вариант, можно считать, то после b += 1 появляется новая переменная с именем b, которая скрывает старую :-) (а ; это лишь частный случай оператора >>= :-))

Begemoth ★★★★★
()
Ответ на: комментарий от anonymous

Это я осознаю. Но почему расхождения в показаниях == и equals начинаются именно после 127?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Если заворачивать int в Integer, то должен быть создан новый объект. Но при этом значения в пределах диапазона byte кэшируются, и соответствующие ссылки будут указывать на один и тот же объект Integer. А за пределами этого диапазона кэширование не происходит, и всегда честно создается новый объект, поэтому оператор == (сравнение ссылок, но не значений!) ведёт себя так странно.

CARS ★★★★
()
Последнее исправление: CARS (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Да, понятно, что объект останется неизменным, но какой тогда вообще смысл говорить о неизменяемости? Разве что удобнее в SSA преобразовывать.

buddhist ★★★★★
()
Ответ на: комментарий от Deleted

Это называется wrapper class caching,

Java Language Specification, chapter 5.1.7:

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.7

stevejobs ★★★★☆
()
Ответ на: комментарий от buddhist

А какой смысл в final по отношению к переменным?

Begemoth ★★★★★
()
Ответ на: комментарий от buddhist

Строку нельзя изменить, можно создать только новую строку, что тут страннного? Иммутабельность же не самой b относиться, а к строкам.

F457 ★★★★
()
Ответ на: комментарий от stevejobs

А, теперь всё ясно. Хотя если бы я встретил такой код в жизни, я бы сказал «WAT».

CYB3R ★★★★★
() автор топика

String — это не primitive type

String это класс.

b += 1;

=== b = b + 1.

=== b = new StringBuilder().append(b).append(1).toString();

итог b == «a1». a == «a».

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)

Вот так надо писать :)

Пример использования в методе testMutableString.

public class MutableStringTest {
    @Test
    public void testMutableString() throws Exception {
        final String s = createModifiableString();
        System.out.println(s);
        modify(s);
        System.out.println(s);
    }

    private final AtomicReference<CharBuffer> cbRef = new AtomicReference<CharBuffer>();

    private String createModifiableString() {
        Charset charset = new Charset("foo", null) {
            @Override
            public boolean contains(Charset cs) {
                return false;
            }

            @Override
            public CharsetDecoder newDecoder() {
                CharsetDecoder cd = new CharsetDecoder(this, 1.0f, 1.0f) {
                    @Override
                    protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
                        cbRef.set(out);
                        while(in.remaining()>0) {
                            out.append((char)in.get());
                        }
                        return CoderResult.UNDERFLOW;
                    }
                };
                return cd;
            }

            @Override
            public CharsetEncoder newEncoder() {
                return null;
            }
        };
        return new String("abc".getBytes(), charset);
    }

    private void modify(String s) {
        CharBuffer charBuffer = cbRef.get();
        charBuffer.position(0);
        charBuffer.put("xyz");
    }

}
stevejobs ★★★★☆
()

Почему именно так?

immutable (в опредеёлнных пределах)

ya-betmen ★★★★★
()

Ох что-то давно я джавы не видел. А как к строке прибавляется единица? Шаблон порвало. Это же не js.

zinfandel ★★
()

Что должен вывести код?

Он не должен скомпилироваться, а если компилируется то эта ваша джава - говно

Debasher ★★★★★
()
Ответ на: комментарий от Debasher

Да вот только оператор + неявно вызывает Object.toString при необходимости.

Begemoth ★★★★★
()

String - это объект, лол.

System.out.println(a) выведет «a».

Присваивание (копирующее) объектов выполняется с помощью метода clone().

LongLiveUbuntu ★★★★★
()
Последнее исправление: LongLiveUbuntu (всего исправлений: 2)
Ответ на: комментарий от LongLiveUbuntu

Присваивание (копирующее) объектов выполняется с помощью метода clone().

Это я знаю и почему-то был уверен, что со стрингом тоже. Но нет.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Это самый базовый уровень, азы, но многие хитрости и нетривиальные вещи там оговариваются. Можно без сдачи чисто потренироваться

GblGbl ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.