为什么不能在Java中将Integer转换为String?


95

我发现了一些奇怪的异常:

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

怎么可能呢?每个对象都可以转换为String,不是吗?

代码是:

String myString = (String) myIntegerObject;

谢谢。


11
“每个对象都可以转换为String” –这是错误的。而是,每个对象都有一个toString()将其转换为字符串的方法。正如几个答案指出的那样,这就是您应该使用的。(对于某些对象,toString()不会返回非常有用的字符串,但是对于Integer,它可能恰好满足您的要求。)
Ted Hopp 2012年

2
""+myIntegerObject也有效:)
Salman von Abbas

1
就我而言,这个错误是错误报告的……我正在使用Integer.toString(IntegerObject),它给了我这个错误,但是对此感到满意IntegerObject.toString()……是的,那确实是一个整数,而且我确实得到了这个错误……
安德鲁(Andrew)

抓紧一点,只有String.valueOf()实际可行……
安德鲁(Andrew)

Answers:


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

@ su-ex (B) objA无法正常工作。(A) objA并且(B) objB会工作。
布山

抱歉,您是对的,这给出了ClassCastException。另外两个是没有用的,但是可以正常工作。
su-ex

45

没有,Integer并且String是不同的类型。要将整数转换为字符串,请使用:String.valueOf(integer),或Integer.toString(integer)表示原始Integer.toString()对象或对象。


1
@Ted Hopp-哪一个?如果是基本类型,则使用前两个,如果是Integer对象,则使用第三个。
Petar Minchev

哎呀。我没有看到您答案的最后一句话。我正在删除我的评论并赞成这个答案。
泰德·霍普

1
相似(但不是重复)的问题:不能将'int'强制转换为String,因为'int'不是对象,更不用说在String层次结构中了。
Kelly S. French

20

对于int类型使用:

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

对于Integer类型使用:

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

这迫使不必要的拆箱操作。
特德·霍普

@Ted Hopp看到我的修改以澄清何时使用每种toString()方法
DRiFTy 2012年

我认为最后一行应该是String myString = myIntegerObject.toString();
Ted Hopp 2012年

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我以为您的意思是您的整数是an int而不是an Integer。如果它已经是一个Integer,只要使用toString()它,并完成。


OP从Integer对象开始。这样做效率更高myIntegerObject.toString()
特德·霍普

4

如果需要字符串表示形式,应调用myIntegerObject.toString()。


2

使用非正式术语,强制转换与Java转换不同。

转换对象意味着该对象已经是您要转换的对象,而您只是将其告知编译器。例如,如果我有一个Foo我知道的引用是一个FooSubclass实例,则(FooSubclass)Foo告诉编译器“不要更改该实例,只要知道它实际上是一个即可FooSubclass

在另一方面,Integer不是一个String,虽然(正如你指出)有充分理由得到一个方法String表示的Integer。由于没有任何实例Integer不可能是a String,所以您不能投IntegerString


1

如果您不需要强制转换,则需要调用toString()。

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

铸件。它是如何工作的?

鉴于:

class A {}
class B extends A {}

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

但无论如何在运行时:

线程“主”中的异常java.lang.ClassCastException:无法将B1强制转换为B2

在您的情况下:

          (对象)
            / \
(整数)(字符串)

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

在运行时:线程“主”中的异常java.lang.ClassCastException:无法将java.lang.Integer强制转换为java.lang.String



0

使用.toString代替,如下所示:

String myString = myIntegerObject.toString();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.