List is an interface, not a class, and interfaces themselves cannot be instantiated. But ArrayList implements the interface List, so you can assign an instance of ArrayList to a variable of type List.
List<Integer> list = new ArrayList<Integer>(); //Example 1
ArrayList<Integer> list = new ArrayList<Integer>(); //Example 2
The advantage of Example 1 is that you can later decide to create another implementation of List (like LinkedList) and all your code that was using the List type for variables will still work without any change. While in Example 2, if you later decide that you need a different type of List, you need to change the type of all your variables that point to the actual object.
How can I initialize List<List<Integer>> in Java?
Use
List<List<Integer>> list = new ArrayList<List<Integer>>();
or since Java 1.7
List<List<Integer>> list = new ArrayList<>();
向上转型。
List是接口而ArrayList与LinkedList为他具体的两个实现类。
ArrayList与LinkedList实现了List接口中定义的通用方法,
但是根据自己的需要也实现了一些List中没有定义的方法。
当你在使用List list = xxx;
的时候,代码表达的语义为:
我需要一个实现了List接口的实现类对象。
具体是哪种实现,我们并不关心。
因为List接口中定义的方法足够我们使用。
这时,这种定义方式,就会发生向上转型。
由具体类型向上转为通用的接口类型。
但是,伴随向上转型时会发生信息丢失,也就是说,
你拿到的这个对象中仅仅只能访问到List接口中定义的成员方法,
而具体实现类新增的扩展方法将会丢失。
所以,在你需要使用一些特殊方法时定义对象需要明确对象类型。
在通用接口提供的内容足以满足当前需求时,就可以向你题目中描述的那样定义。十分方便。
// 1.这样你就只能调用List接口里面定义好的方法,而不能使用你自己在ArrayList扩展的方法。
List list = new ArrayList();
// 2.这样你可以使用自己在ArrayList类上扩展的方法
ArrayList list = new ArrayList();
// 接口就是定义了一些行为,它要求你应该做什么。
// 假如你采用了面向接口编程方式,也就是第一种方式:List list = new ArrayList();
// 就能通过接口很大限度上规范开发人员的实现规则,因为你现在只能调用接口的方法。