java.lang.ClassCastException你是怎麼處理的?

事件起因

在做一個類型轉換時遇到了下面的異常:
在這裏插入圖片描述

是說不能把 Integer 類型強制轉換成 String 類型。

我的測試代碼大概是這個樣子:

public static void testClassCastException() {
  Integer i1 = Integer.valueOf(getT()); // ① 拋異常
  Integer i2 = (Integer) getT(); // ② 正常
  Integer i3 = Integer.valueOf(getT().toString()); // ③ 正常
}

private static <T> T getT() {
  return (T) new Integer(10);
}

// ①和③的不同在於Integer.valueOf()裏的參數的類型,其實Integer.valueOf()方法就是需要String類型的,所以我們直接用Integer類型當然在底層是不識別的。
// ①和②的不同在於類型轉換的方式,這個就引申出下面這個問題了。

(String)、toString、String.valueOf 的區別

  1. toString()
    toString()是在 Object 中定義的,因此,任何繼承 Object 的類都具有這個方法。

​ 在 API 中 toString()被描述爲:

​ 返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。結果應是一個簡明但易於讀懂的信息表達式。建議所有子類都重寫此方法。

Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等於:getClass().getName()+’@’+Integer.toHexString(hashCode())
  我們在定義一個類的時候可以重寫繼承自 Object 的 toString()方法,以此來表示該對象的基本信息。
  但是,使用 toString()的對象不能爲 null,否則會拋出異常 java.lang.NullPointerException。

  1. String.valueOf()
    String.valueOf()解決了 toString()使用對象不能爲空的問題,實際上,該方法在底層還是使用了 toString()。如下源碼:
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

值得注意的是,如果使用對象爲 null,返回的結果是字符串”null”,而不是對象 null。
  在很多時候使用 String.valueOf()比使用 toString()更能減少報錯的機會,因爲不用考慮是否爲 null 的情況。但是,也要特別注意:if(String.valueOf(o) == null){…}這樣的代碼肯定就回有問題,因爲永遠不會得到執行。

  1. (String)
    (String)區別於上面兩種方法,因爲它是強制轉換。
    每個對象在創建的時候就已經確定了類型不能改變,所謂的強制轉換隻是表面上將其轉換成了另一種類型,就相當於 A 被當成了 B 使用,如果 A 能夠被當成 B,那一切沒有問題,但是 A 做不了 B,就只能拋出異常,說我做不到。
Integer o = new Integer(100);
System.out.println((String)o);

如上代碼編譯時就會報錯:Cannot cast Integer to String,說明 Integer 不能通過強制轉換成 String。
  而我們一開始的代碼:

Object x = new Integer(0);
System.out.println((String)x);

​ 在編譯時沒錯,運行時拋出異常。這是因爲 x 在表面上是 Object,實際上是 Integer。而 Object 是可以通過強制轉換成爲 String 的。所以,在編譯的時候,x 被當成了 Object,大家相安無事,真正運行的時候,x 被查出來是 Integer,理所當然就拋出了 ClassCastException。

最安全的方法:instanceof

取到的對象進行類型轉換如果不知道具體會是什麼類型的,可以通過instanceof關鍵字來檢查改對象屬於哪個類型的,再具體去進行某些業務。

PS:a instanceof b的結果和b.class.isInstance(a)的結果是一致的,可以實現相同的功能,完全等價。

爲什麼在 Java 裏不能將 Integer 強制轉換成 String

因爲 StringInteger 不是在同一個對象階層。

      Object
     /      \
    /        \
String     Integer

當你嘗試強制轉換時,僅僅會在同一個對象階層轉換。比如:

     Object
     /
    /
   A
  /
/
B

在這種情況,(A)objB 或者 (Object)objB 或者 (Object)objA 可以進行轉換。

正如其他人已經提到,將integer轉換成String可以使用以下方法:

基本類型的整型時使用:String.valueOf(integer)或者Integer.toString(integer) 來轉換成String
Integer對象型時使用:Integer.toString()轉換成String

參考:

翻譯|爲什麼在 Java 裏不能將 Integer 強制轉換成 String | PostgreSQL DBA

java.toString() ,(String),String.valueOf 的區別 _java_springk 的專欄-CSDN 博客


求關注、分享、在看!!! 你的支持是我創作最大的動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章