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


95

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

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

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

Код такой:

String myString = (String) myIntegerObject;

Спасибо.


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();

Это вызывает ненужную операцию распаковки.
Тед Хопп

@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().
Тед Хопп


2

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

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

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


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 (целое число) .

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


Как сказал Петар выше, так и должно бытьString.valueOf(integer)
Урс Реупке

@UrsReupke: спасибо, вообще-то, когда я пытался добавить ссылку, я переписал ее неправильно.
RanRag

0

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

String myString = myIntegerObject.toString();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.