Как класс String переопределяет оператор +?

Почему в Java вы можете добавлять строки с оператором +, когда String является классом? В коде String.java я не нашел никакой реализации для этого оператора. Означает ли это понятие объектная ориентация?

Ответ 1

Посмотрите на следующие простые выражения в Java

int x=15;
String temp="x = "+x;

Компилятор преобразует "x = "+x; в StringBuilder внутренне и использует .append(int) для "добавления" целых чисел в строку.

5.1.11. Преобразование строк

Любой тип может быть преобразован в тип String путем преобразования строки.

Значение х примитивного типа T сначала преобразуется в опорное значение как если бы он передал его как аргумент соответствующему экземпляру класса (§15.9):

  • Если T булево, то используйте новый Boolean (x).
  • Если T char, используйте новый символ (x).
  • Если T является байтом, коротким или int, то используйте новый Integer (x).
  • Если T длинно, используйте новый Long (x).
  • Если T является float, используйте новый Float (x).
  • Если T двойное, используйте новый Double (x).

Это ссылочное значение затем преобразуется в тип String по строке преобразование.

Теперь нужно учитывать только опорные значения:

  • Если ссылка имеет значение null, она преобразуется в строку "null" (четыре символа ASCII n, u, l, l).
  • В противном случае преобразование выполняется как бы путем вызова метода toString ссылочного объекта без аргументов; но если результат вызова метода toString равен нулю, тогда Вместо этого используется строка "null".

Метод toString определяется примитивным классом Object (§4.3.2). Многие классы переопределяют его, в частности Boolean, Character, Integer, Long, Float, Double и String.

Подробнее о контексте преобразования строк см. в п. 5.4.

15.18.1.

Оптимизация конкатенации строк:Реализация может выбрать выполнение преобразования и конкатенации в один шаг, чтобы избежать создания и затем отбрасывания промежуточного Строковый объект. Чтобы увеличить производительность повторяющейся строки concatenation, компилятор Java может использовать класс StringBuffer или аналогичная техника для уменьшения количества промежуточных объектов String которые создаются путем оценки выражения.

Для примитивных типов реализация также может оптимизировать создание объекта-обертки путем преобразования непосредственно из примитива введите строку.

Оптимизированная версия на самом деле не сделает полное завершенное преобразование String.

Это хорошая иллюстрация оптимизированной версии, используемой компилятором, хотя и без преобразования примитива, где вы можете видеть, как компилятор меняет вещи на StringBuilder в фоновом режиме:

http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/


Этот код Java:

public static void main(String[] args) {
    String cip = "cip";
    String ciop = "ciop";
    String plus = cip + ciop;
    String build = new StringBuilder(cip).append(ciop).toString();
}

Генерирует это - посмотрим, как два стиля конкатенации приводят к одному и тому же байт-коду:

 L0
    LINENUMBER 23 L0
    LDC "cip"
    ASTORE 1
   L1
    LINENUMBER 24 L1
    LDC "ciop"
    ASTORE 2

   // cip + ciop

   L2
    LINENUMBER 25 L2

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 3

    // new StringBuilder(cip).append(ciop).toString()

   L3
    LINENUMBER 26 L3

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 4
   L4
    LINENUMBER 27 L4
    RETURN

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

cip+ciop; 

в

new StringBuilder(cip).append(ciop).toString();

Другими словами, оператор + в конкатенации строк является эффективным сокращением для более подробного StringBuilder -идиома.

Ответ 2

Это функция компилятора Java, которая проверяет операнды оператора +. И на основе операндов он генерирует байтовый код:

  • Для String он генерирует код для concat строк
  • Для чисел, он генерирует код для добавления чисел.

Вот что говорит спецификация Java:

Операторы + и - называются аддитивными операторами.     АддитивноеВыражение:         МультипликативноеВыражение         AdditiveExpression + MultiplicativeExpression         AdditiveExpression - Мультипликативное выражение

Операторы-добавки имеют одинаковый приоритет и синтаксически     левые ассоциативные (они группируются слева направо). Если тип     операндом оператора + является String, тогда операция представляет собой конкатенацию строк.

В противном случае тип каждого из операндов оператора + должен быть типом, который     (§5.1.8) является примитивным числовым типом, или возникает ошибка времени компиляции.

В каждом случае тип каждого из операндов двоичного оператора - должен быть     тип, который является конвертируемым (п. 5.1.8), к примитивному числовому типу или     ошибка времени компиляции.

Ответ 3

Как класс String переопределяет + оператор?

Это не так. Компилятор делает это. Строго говоря, компилятор перегружает оператор + для операндов String.

Ответ 4

Прежде всего (+) перегружен не переопределенным

Язык Java обеспечивает специальную поддержку для строки оператор конкатенации (+), который был перегружен для строк Java объекты.

  • Если операнд левой стороны - String, он работает как конкатенация.

  • Если операнд левой стороны - Integer, он работает как оператор сложения

Ответ 5

Язык Java обеспечивает специальную поддержку оператора конкатенации строк (+) и для преобразования других объектов в строки. Конкатенация строк реализуется с помощью класса StringBuilder (или StringBuffer) и его метода append.

Ответ 6

Значение оператора + при применении к String определяется языком, как все уже написано. Поскольку вы, кажется, не находите это достаточно убедительным, подумайте об этом:

Ints, float и doubles имеют разные двоичные представления, и поэтому добавление двух ints - это другая операция с точки зрения манипуляции с битами, чем добавление двух float: для ints вы можете добавлять побиты, перенося бит и проверяя переполнение; для поплавков вы должны иметь дело с мантиссами и экспонентами отдельно.

Итак, в принципе "добавление" зависит от природы добавляемых объектов. Java определяет его для строк, а также для int и float (longs, double,...)

Ответ 7

Оператор + обычно заменяется на StringBuilder во время компиляции. Подробнее см. .