Почему нельзя преобразовать Integer в String в Java?

95

Нашел странное исключение:

java.lang.ClassCastException: java.lang.Integer 
 cannot be cast to java.lang.String

Как это возможно? Каждый объект можно преобразовать в String, не так ли?

Код такой:

String myString = (String) myIntegerObject;

Спасибо.

user710818
источник
11
«Каждый объект можно преобразовать в String» - это неправильно. Скорее, у каждого объекта есть toString()метод, который преобразует его в String. Как указано в нескольких ответах, это то, что вы должны использовать. (Для некоторых объектов toString()не возвращает очень полезную строку, но для Integer, вероятно, делает именно то, что вы хотите.)
Тед Хопп
2
""+myIntegerObjectтоже работает :)
Salman von Abbas
1
В моем случае об этой ошибке сообщалось по ошибке ... Я использовал, Integer.toString(IntegerObject)и она дала мне эту ошибку, но она довольна IntegerObject.toString()... И да, это действительно целое число, и я действительно получил эту ошибку ...
Andrew
Поцарапайте это, только на String.valueOf()самом деле работает ...
Эндрю

Ответы:

155

Почему это невозможно:

Поскольку String и Integer не находятся в одной иерархии объектов.

      Object
     /      \
    /        \
String     Integer

Приведение, которое вы пытаетесь выполнить, работает, только если они находятся в одной иерархии, например

      Object
     /
    /
   A
  /
 /
B

В этом случае (A) objBили (Object) objBили (Object) objAбудет работать.

Следовательно, как уже упоминалось другими, для преобразования целого числа в строку используйте:

String.valueOf(integer), или Integer.toString(integer)для примитивов,

или

Integer.toString() для объекта.

Бхушан
источник
А как насчет (A) objA, (B) objB и (B) objA?
вс-экс
@ su-ex (B) objAне сработает. (A) objAи (B) objBбудет работать.
Bhushan
Извините, вы правы, это дает ClassCastException. Два других совершенно бесполезны, но, конечно, будут работать.
вс-вс,
45

Нет, Integerи Stringбывают разные типы. Чтобы преобразовать целое число в строку, используйте:, String.valueOf(integer)или Integer.toString(integer)для примитива, или Integer.toString()для объекта.

Петр Минчев
источник
1
@ Тед Хопп - какой? Если это примитив, используйте первые два, если это объект Integer, используйте третий.
Петар Минчев
Ой. Я не видел последней фразы вашего ответа. Я удаляю свой комментарий и поддерживаю этот ответ.
Тед Хопп,
1
Похожая (но не повторяющаяся) проблема: int нельзя преобразовать в String, потому что int не является объектом, тем более в иерархии String.
Келли С. Френч
20

Для intтипов используют:

int myInteger = 1;
String myString = Integer.toString(myInteger);

Для Integerтипов используют:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();
DRiFTy
источник
Это вызывает ненужную операцию распаковки.
Тед Хопп
@Ted Hopp, посмотрите мои правки, чтобы прояснить, когда использовать каждый тип toString()метода
DRiFTy
Я думаю, что последняя строчка должна бытьString myString = myIntegerObject.toString();
Тед Хопп
6

Нет. Каждый объект может быть преобразован в java.lang.Object, а не в String. Если вам нужно строковое представление любого объекта, вы должны вызвать toString()метод; это не то же самое, что преобразование объекта в строку.

андри
источник
5

Объекты можно преобразовать в строку с помощью toString()метода:

String myString = myIntegerObject.toString();

По поводу кастинга такого правила нет . Чтобы приведение работало, объект должен действительно быть того типа, к которому вы выполняете приведение.

миллимеш
источник
5

Вы не можете отбрасывать явно ничего к Stringчто не String. Вы должны использовать либо:

"" + myInt;

или:

Integer.toString(myInt);

или:

String.valueOf(myInt);

Я предпочитаю вторую форму, но считаю, что это личный выбор.

Редактировать ОК, вот почему я предпочитаю вторую форму. Первая форма при компиляции могла создавать экземпляр StringBuffer(в Java 1.4) или StringBuilderв 1.5; еще одна вещь, которую нужно собрать мусором. Насколько я могу судить, компилятор не оптимизирует это. Вторая форма также имеет аналог, Integer.toString(myInt, radix)который позволяет вам указать, хотите ли вы шестнадцатеричный, восьмеричный и т. Д. Если вы хотите быть последовательным в своем коде (чисто эстетически, я думаю), вторую форму можно использовать в большем количестве мест.

Изменить 2 Я предположил, что вы имели в виду, что ваше целое число было, intа не Integer. Если он уже есть Integer, просто используйте toString()его и готово.

Джонатан
источник
OP начинается с объекта Integer. Гораздо эффективнее просто делать myIntegerObject.toString().
Тед Хопп
4

Вы должны вызвать myIntegerObject.toString (), если хотите строковое представление.

Савино Сгера
источник
2

Приведение отличается от преобразования в Java, если использовать неформальную терминологию.

Приведение объекта означает, что объект уже является тем, к чему вы его приводите, и вы просто сообщаете об этом компилятору. Например, если у меня есть Fooссылка, которая, как я знаю, является FooSubclassэкземпляром, то (FooSubclass)Fooкомпилятор сообщает компилятору: «Не меняйте экземпляр, просто знайте, что это на самом деле FooSubclass.

С другой стороны, an неInteger является a , хотя (как вы указываете) существуют методы для получения a , представляющего . Поскольку ни один экземпляр не может быть a , вы не можете преобразовать его в .StringStringIntegerIntegerStringIntegerString

Yshavit
источник
1

В вашем случае кастинг не требуется, вам нужен вызов toString ().

Integer i = 33;
String s = i.toString();
//or
s = String.valueOf(i);
//or
s = "" + i;

Кастинг. Как это работает?

Дано:

class A {}
class B extends A {}

(А)
  |
(В)

B b = new B(); //no cast
A a = b;  //upcast with no explicit cast
a = (A)b; //upcast with an explicit cast
b = (B)a; //downcast

A и B в одном дереве наследования, и мы можем это:

a = new A();
b = (B)a;  // again downcast. Compiles but fails later, at runtime: java.lang.ClassCastException

Компилятор должен разрешать вещи, которые могут работать во время выполнения. Однако, если компилятор на 100% знает, что приведение не может работать, компиляция завершится ошибкой.
Дано:

class A {}
class B1 extends A {}
class B2 extends A {}

        (А)
      / \
(В1) (В2)

B1 b1 = new B1();
B2 b2 = (B2)b1; // B1 can't ever be a B2

Ошибка: неконвертируемые типы B1 и B2. Компилятор на 100% знает, что приведение не может работать. Но вы можете обмануть компилятор:

B2 b2 = (B2)(A)b1;

но в любом случае во время выполнения:

Исключение в потоке "main" java.lang.ClassCastException: B1 не может быть преобразован в B2

в твоем случае:

          (Объект)
            / \
(Целое число) (Строка)

Integer i = 33;
//String s = (String)i; - compiler error
String s = (String)(Object)i;

во время выполнения: исключение в потоке «main» java.lang.ClassCastException: java.lang.Integer не может быть преобразован в java.lang.String

Дмитрий Соколюк
источник
0

Используйте String.valueOf (целое число) .

Он возвращает строковое представление целого числа.

RanRag
источник
Как сказал Петар выше, так и должно бытьString.valueOf(integer)
Урс Реупке
@UrsReupke: спасибо, вообще-то, когда я пытался добавить ссылку, я переписал ее неправильно.
RanRag
0

Вместо этого используйте .toString, как показано ниже:

String myString = myIntegerObject.toString();
А.Алим11
источник