iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Software Development

深入淺出Java 30天系列 第 29

Day 29: 優先使用list而不是array(上)

  • 分享至 

  • xImage
  •  

今天和明天會說明為什麼最好優先使用lists,並且說明arrays跟lists有什麼差異,所以才會這麼建議。

array跟list有什麼不同?

arrays是協變(covariant),lists是無變化(invariant)

協變(covariant)的意思是指,可以因為類別之間是繼承關係,兩個array也是繼承關係,舉例來說,Object這個類別是所有類別的父類別,所以Object[]會是Long[]的父類別。list是無變化(invariant)指的是兩個list不會因為型別參數(type parameters)之間有繼承關係,兩個list就有繼承關係,舉例來說,List<Object>不會是List<Long>的父類別。array跟list的這種差異,會讓他們在不小心給錯型別的時候,跳出錯誤的時間點不一樣。

從下面的範例可以看到,在宣告的時候,實體化不同類別的array,因為Object[]Long[]是協變(covariant)關係,所以compile的時候順利過關,但是Long[]終究不能接受型態非Long的物件,runtime的時候才跳出錯誤。

public class TestArrayAndList {
    public static void main(String[] args) {
        Object[] objectArray = new Long[1];
        objectArray[0] = "I don't fit in";
    }
}


但是list就不一樣,list之間的型別參數不會有任何關係,compile的時候就跳出錯誤訊息。兩個範例相比之下,list更容易debug,這也是優先使用list而不是array的原因之一。

import java.util.ArrayList;
import java.util.List;

public class TestArrayAndList {
    public static void main(String[] args) {
        List<Object> objectList = new ArrayList<Long>();
        objectList.add("I don't fit in");
    }
}


當然,list有另外一種更安全更方便的寫法。在Java 7提供菱形運算符(Diamond Operator)之後,右邊的型別參數可以省略,就沒有寫錯型別參數的問題了。

import java.util.ArrayList;
import java.util.List;

public class TestArrayAndList {
    public static void main(String[] args) {
        List<Object> objectList = new ArrayList<>();
        objectList.add("I don't fit in");
    }
}

array是具體化(reified),泛型的list是擦除(erasure)

這個差異是,array在runtime還會保持型別,而泛型的list,型別參數的型別只有在compile的時候存在,runtime的時候就會被擦除。這也是為什麼,array在runtime會型別錯誤,並跳出錯誤訊息,而使用泛型的list不會,因為compile的時候檢查完了,後面runtime就沒有型別了。


上一篇
Day 28: 不建議在Java 5之後的新程式碼使用raw type(下)
下一篇
Day 30: 優先使用list而不是array(下)
系列文
深入淺出Java 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言