#java #type-conversion #string-concatenation
#java #преобразование типов #конкатенация строк
Вопрос:
Мне нужно напечатать ‘H3110 w0r1d 2.0 true‘ в качестве выходных данных. Ниже приведен написанный код, который выводится как ‘3182 w0r1d 2.0 true’.
public class HelloWorld {
public static void main (String[] args){
char c1= 'H';
int num1 = 3110;
char c2='w';
byte b=0;
char c3='r';
int y=1;
char c4='d';
float f = 2.0f;
boolean bool= true;
String s = c1 num1 " " c2 b c3 y c4 " " f " " bool;
System.out.println(s);
}
}
Запрос: Если я объединяю H
и 3110
, он печатается как 3182
. Почему так?
Комментарии:
1. Потому
char
int
что, по сути, продвигается до добавления. Если вместо этого вы используете строку (string c1 = "H";
), все будет хорошо.2. В подобной ситуации
char int
char
сначала преобразуетсяint
в (соответствующее значение в Юникоде (для начинающих, в данном случае индекс в таблице ASCII)), а затем это обычноеint int
дополнение.
Ответ №1:
Оператор не использует конкатенацию строк, если хотя бы один операнд не имеет тип String
. Игнорируя остальные
операторы, вы в основном ищете «что произойдет, если я добавлю char
и int
вместе» — и ответ: « char
повышается до int
, и выполняется обычное сложение целых чисел». Повышенное значение 'H'
равно 72 (поскольку это числовое значение ‘H’ в формате UTF-16), следовательно, результат 3182.
Самым простым решением для этого в вашем случае было бы изменить тип c1
на String
вместо char
:
String c1 = "H";
Тогда вместо сложения целых чисел будет использоваться конкатенация строк.
Комментарии:
1. Ну, если быть точным,
'H'
равно 72 даже без повышения доint
, посколькуchar
это 16-разрядное целое число без знака в соответствии со спецификацией языка Java.2. Хорошее объяснение, однако использование StringBuilder безопаснее.
3. @IQbrod Safer может быть неправильным термином, объясняющим, почему
StringBuilder
следует предпочесть. Производительность может быть более точной. Однако обратите внимание, что в этой конкретной ситуации это не применимо, поскольку Java уже оптимизирует конкатенацию с одним оператором, т.Е.a b c d
(Используя сам StringBuilder в более ранних версиях и даже улучшенные механизмы впоследствии).
Ответ №2:
Вы должны использовать StringBuilder
введенный в Java 5, который имеет методы .append()
с char / int / long и т.д… Этот класс является правильным конкатенатором строк в Java и позволяет вам объединять любой примитив (char / int / long …) по его строковому представлению.
System.out.println(4 3 "s"); // will print "7s"
System.out.println(StringBuilder.append(4).append(3).append("s").toString()); // will print "43s"
Как упоминалось @Zabuzard, компилятор Java заменит строку sum (
) на a StringBuilder
, но char int
возвращает an int
(и int
не является a String
).
Чтобы получить подробное объяснение о char int
возврате int
. Я предлагаю вам @JonSkeet ответить 🙂
public class Main {
public static void main(String[] args) {
char c1= 'H';
int num1 = 3110;
char c2='w';
byte b=0;
char c3='r';
int y=1;
char c4='d';
float f = 2.0f;
boolean bool= true;
String s = new StringBuilder()
.append(c1)
.append(num1)
.append(c2)
.append(b)
.append(c3)
.append(y)
.append(c4)
.append(f)
.append(bool)
.toString();
System.out.println(s);
}
}
Комментарии:
1. Хотя этот ответ дает ценное решение, было бы также неплохо, если бы он объяснил проблему OPs и почему она устраняет проблему.
2. @Zabuzard Джон сделал это отлично, я не буду копировать и вставлять его ответ
3. Справедливо. Однако обратите внимание , что в этой конкретной ситуации
StringBuilder
простая конкатенация не имеет никаких преимуществa b c d
. Поскольку JLS требует, чтобы любая реализация Java уже оптимизировала такие конкатенации.StringBuilder
имеет преимущества в производительности только в том случае, если конкатенация выполняется по нескольким операторам (обычно в цикле).4. OP ожидает
в качестве конкатенатора строк, но в Java используется правильный конкатенатор строк,
StringBuilder.append()
который предотвращает путаницуchar int
при возвратеint
5. Это справедливо, вот почему я бы предложил добавить более подробное объяснение, чтобы подчеркнуть этот аспект.
Ответ №3:
Другим решением этой проблемы может быть использование статического метода
String.valueOf(c1)
Лучшим способом является использование ранее упомянутого StringBuilder, но использование String.valueOf — другое решение с меньшим эффектом для кода, чем при использовании StringBuilder.
Комментарии:
1. Спасибо всем вам за подробное объяснение