Tại sao không thể truyền Integer thành String trong java?


95

Tôi tìm thấy một số ngoại lệ kỳ lạ:

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

Làm thế nào nó có thể được? Mỗi đối tượng có thể được chuyển thành Chuỗi, phải không?

Mã là:

String myString = (String) myIntegerObject;

Cảm ơn.


11
"Mỗi đối tượng có thể được ép kiểu thành Chuỗi" - Điều này sai. Đúng hơn, mọi đối tượng đều có một toString()phương thức sẽ chuyển đổi nó thành Chuỗi. Như một số câu trả lời đã chỉ ra, đó là những gì bạn nên sử dụng. (Đối với một số đối tượng, toString()không trả lại rất hữu ích chuỗi, nhưng đối với Integer, nó có thể thực hiện chính xác những gì bạn muốn.)
Ted Hopp

2
""+myIntegerObjectcũng hoạt động :)
Salman von Abbas

1
Trong trường hợp của tôi, lỗi này được báo cáo là do lỗi ... Tôi đang sử dụng Integer.toString(IntegerObject)và nó đã cho tôi lỗi này, nhưng thật hạnh phúc với IntegerObject.toString()... Và vâng, đó thực sự là một Số nguyên, và tôi thực sự đã gặp lỗi này ...
Andrew

Scratch rằng, chỉ String.valueOf()thực sự hoạt động ...
Andrew

Câu trả lời:


155

Tại sao điều này là không thể:

Bởi vì Chuỗi và Số nguyên không nằm trong cùng một hệ thống phân cấp Đối tượng.

      Object
     /      \
    /        \
String     Integer

Truyền mà bạn đang thử, chỉ hoạt động nếu chúng ở trong cùng một hệ thống phân cấp, ví dụ:

      Object
     /
    /
   A
  /
 /
B

Trong trường hợp này, (A) objBhay (Object) objBhoặc (Object) objAsẽ làm việc.

Do đó, như những người khác đã đề cập, để chuyển đổi một số nguyên thành chuỗi sử dụng:

String.valueOf(integer)hoặc Integer.toString(integer)cho nguyên thủy,

hoặc là

Integer.toString() cho đối tượng.


Còn (A) objA, (B) objB và (B) objA thì sao?
su-ex

@ su-ex (B) objAsẽ không hoạt động. (A) objA(B) objBsẽ hoạt động.
Bhushan

Xin lỗi, bạn nói đúng, điều này cung cấp một ClassCastException. Hai cái còn lại khá vô dụng nhưng tất nhiên sẽ hiệu quả.
su-ex

45

Không, IntegerStringlà các loại khác nhau. Để chuyển đổi một số nguyên thành chuỗi, hãy sử dụng:, String.valueOf(integer)hoặc Integer.toString(integer)cho nguyên thủy hoặc Integer.toString()cho đối tượng.


1
@Ted Hopp - cái nào? Nếu nó là một nguyên thủy sử dụng hai đầu tiên, nếu nó là một đối tượng Integer sử dụng một trong những thứ ba.
Petar Minchev

Giáo sư. Tôi không thấy cụm từ cuối cùng trong câu trả lời của bạn. Tôi đang xóa bình luận của mình và tán thành câu trả lời này.
Ted Hopp

1
Vấn đề tương tự (nhưng không trùng lặp): một 'int' không thể được chuyển thành Chuỗi vì 'int' không phải là một đối tượng, ít hơn nhiều trong hệ thống phân cấp Chuỗi.
Kelly S. French

20

Đối với intcác loại sử dụng:

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

Đối với Integercác loại sử dụng:

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

Điều này buộc thực hiện thao tác mở hộp không cần thiết.
Ted Hopp

@Ted Hopp thấy sửa của tôi để làm rõ khi nào thì sử dụng từng loại toString()phương pháp
DRiFTy

Tôi nghĩ rằng dòng cuối cùng nênString myString = myIntegerObject.toString();
Ted Hopp

6

Không. Mọi đối tượng đều có thể được đúc thành một java.lang.Object, không phải a String. Nếu bạn muốn biểu diễn chuỗi của bất kỳ đối tượng nào, bạn phải gọi toString()phương thức; điều này không giống như truyền đối tượng thành một chuỗi.


5

Các đối tượng có thể được chuyển đổi thành một chuỗi bằng toString()phương pháp:

String myString = myIntegerObject.toString();

Không có quy tắc như vậy về đúc . Để truyền hoạt động, đối tượng thực sự phải thuộc loại bạn đang truyền.


5

Bạn không thể truyền một cách rõ ràng bất cứ thứ gì đến một Stringkhông phải là a String. Bạn nên sử dụng:

"" + myInt;

hoặc là:

Integer.toString(myInt);

hoặc là:

String.valueOf(myInt);

Tôi thích hình thức thứ hai hơn, nhưng tôi nghĩ đó là lựa chọn cá nhân.

Chỉnh sửa OK, đây là lý do tại sao tôi thích biểu mẫu thứ hai hơn. Dạng đầu tiên, khi được biên dịch, có thể khởi tạo a StringBuffer(trong Java 1.4) hoặc a StringBuildertrong 1.5; một điều nữa để được thu gom rác. Trình biên dịch không tối ưu hóa điều này theo như tôi có thể nói. Biểu mẫu thứ hai cũng có một tương tự, Integer.toString(myInt, radix)cho phép bạn chỉ định xem bạn có muốn hex, bát phân, v.v. Nếu bạn muốn nhất quán trong mã của mình (tôi đoán hoàn toàn về mặt thẩm mỹ), biểu mẫu thứ hai có thể được sử dụng ở nhiều nơi hơn.

Chỉnh sửa 2 Tôi cho rằng ý của bạn là số nguyên của bạn là một intchứ không phải một Integer. Nếu nó đã là một Integer, chỉ cần sử dụng toString()trên nó và được thực hiện.


OP đang bắt đầu với một đối tượng Integer. Nó hiệu quả hơn nhiều để chỉ làm myIntegerObject.toString().
Ted Hopp

4

Bạn nên gọi myIntegerObject.toString () nếu bạn muốn biểu diễn chuỗi.


2

Truyền khác với chuyển đổi trong Java, sử dụng thuật ngữ không chính thức.

Truyền một đối tượng có nghĩa là đối tượng đó đã là thứ mà bạn đang truyền nó tới và bạn chỉ nói với trình biên dịch về nó. Ví dụ: nếu tôi có một Footham chiếu mà tôi biết là một FooSubclassthể hiện, thì hãy (FooSubclass)Foonói với trình biên dịch, "đừng thay đổi thể hiện, chỉ cần biết rằng nó thực sự là một FooSubclass.

Mặt khác, một Integerkhông một String, mặc dù (như bạn chỉ ra) có những phương pháp để có được một Stringđại diện cho một Integer. Vì không có phiên bản nào của Integercó thể là a String, bạn không thể truyền Integerđến String.


1

Trong trường hợp của bạn không cần truyền, bạn cần gọi toString ().

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

Vật đúc. Làm thế nào nó hoạt động?

Được:

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 và B trong cùng một cây thừa kế và chúng ta có thể:

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

Trình biên dịch phải cho phép những thứ có thể hoạt động trong thời gian chạy. Tuy nhiên, nếu trình biên dịch biết 100% rằng quá trình truyền không thể hoạt động, thì quá trình biên dịch sẽ thất bại.
Được:

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

Lỗi: Không thể chuyển đổi loại B1 và ​​B2. Trình biên dịch biết 100% rằng dàn diễn viên không thể hoạt động. Nhưng bạn có thể gian lận trình biên dịch:

B2 b2 = (B2)(A)b1;

nhưng dù sao trong thời gian chạy:

Ngoại lệ trong luồng "main" java.lang.ClassCastException: B1 không thể được truyền sang B2

trong trường hợp của bạn:

          (Đối tượng)
            / \
(Số nguyên) (Chuỗi)

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

trong thời gian chạy: Ngoại lệ trong luồng "main" java.lang.ClassCastException: java.lang.Integer không thể được truyền sang java.lang.String


0

Sử dụng String.valueOf (số nguyên) .

Nó trả về một biểu diễn chuỗi của số nguyên.


Như Petar nói ở trên, bạn cần phảiString.valueOf(integer)
Urs Reupke

@UrsReupke: cảm ơn, thực sự khi tôi cố gắng thêm liên kết, tôi đã viết lại sai.
RanRag

0

Sử dụng .toString thay thế như bên dưới:

String myString = myIntegerObject.toString();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.