Почему нельзя привести Integer к String в Java? - PullRequest
91 голосов
/ 23 января 2012

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

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

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

Код:

String myString = (String) myIntegerObject;

Спасибо.

Ответы [ 11 ]

142 голосов
/ 23 января 2012

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

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

      Object
     /      \
    /        \
String     Integer

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

      Object
     /
    /
   A
  /
 /
B

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

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

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

или

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

45 голосов
/ 23 января 2012

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

20 голосов
/ 23 января 2012

Для int типов использования:

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

Для Integer типов использования:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();
6 голосов
/ 23 января 2012

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

5 голосов
/ 23 января 2012

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

"" + myInt;

или

Integer.toString(myInt);

или

String.valueOf(myInt);

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

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

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

4 голосов
/ 23 января 2012

Объекты могут быть преобразованы в строку с использованием метода toString():

String myString = myIntegerObject.toString();

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

4 голосов
/ 23 января 2012

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

2 голосов
/ 23 января 2012

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

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

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

1 голос
/ 21 декабря 2016

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

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

литье. Как это работает?

Дано:

class A {}
class B extends A {}

(А)
|
(B)

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 {}

(А)
/ \
(B1) (B2)

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 голосов
/ 03 марта 2017

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

String myString = myIntegerObject.toString();
...