Чому не можна передати Integer у рядок у Java?


95

Я знайшов якийсь дивний виняток:

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

Як це може бути можливим? Кожен об'єкт можна передати в рядок, чи не так?

Код:

String myString = (String) myIntegerObject;

Дякую.


11
"Кожен об'єкт можна передати в рядок" - Це неправильно. Швидше, кожен об’єкт має toString()метод, який перетворить його на рядок. Як вказує кілька відповідей, саме цим слід користуватися. (Для деяких об’єктів toString()не повертає дуже корисний рядок, але Integer, мабуть, робить саме те, що ви хочете.)
Тед Хопп,

2
""+myIntegerObjectтакож працює :)
Сальман фон Аббас

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) objA та (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" не можна передавати до рядка, оскільки "int" не є об'єктом, тим більше в ієрархії рядка.
Kelly S. French

20

Для intвикористання типів:

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

Для Integerвикористання типів:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();

Це змушує зайву операцію розпакування.
Тед Хопп,

@ Тед Хопп бачить мої правки, щоб пояснити, коли використовувати кожен тип 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);

Я віддаю перевагу другій формі, але я думаю, що це особистий вибір.

Редагувати добре, ось чому я віддаю перевагу другій формі. Перша форма при компіляції може створити екземпляр a StringBuffer(у Java 1.4) або a StringBuilderу 1.5; ще одна річ - збирати сміття. Компілятор не оптимізує це, наскільки я міг сказати. Друга форма також має аналог,Integer.toString(myInt, radix) який дозволяє вказати, чи потрібно вам шістнадцяткові, вісімкові та ін. Якщо ви хочете бути послідовними у своєму коді (суто естетично, я думаю), другу форму можна використовувати в інших місцях.

Редагувати 2 Я припускав, що ви мали на увазі, що ваше ціле число - це intа не an 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 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 {}

        (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

Використовуйте String.valueOf (ціле число) .

Він повертає рядкове представлення цілого числа.


Як Петро сказав вище, це повинно бутиString.valueOf(integer)
Урс Репке

@UrsReupke: дякую, насправді, коли я намагався додати посилання, я переписав його неправильно.
RanRag

0

Замість цього використовуйте .toString, як показано нижче:

String myString = myIntegerObject.toString();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.