我是 Java 的初学者。我有两个基本问题。
当我们将数组列表的声明写为
List l=new ArrayList<String>();List<String> l=new ArrayList<String>();List<String> l=new ArrayList<>();我看到以上所有陈述都没有给出任何错误。当我们选择其中一种方法来声明任何集合时,它会产生什么不同?
当我们将集合初始化为
List<String>l = new ArrayList<String>();所以如果我们像下面这样声明
ArrayList<String> l= new ArrayList<String>();1 和 2 有什么区别,为什么我们在使用集合时主要选择 2?
a)
List l = new ArrayList<String>();与 相同List<Object> l = new ArrayList<String>();。这意味着该变量l是一个可以存储 any 的列表Object,但不仅仅是一个字符串。如果您想将它们用作字符串,您还需要转换列表的值。所以下面的代码会编译(这通常不是你想要的):
List l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//adding an int is not realy expected here, but works
l.add(new Date());//also adding any other object is allowed
String s = (String) l.get(0);//s will be "a string"
String s2 = (String) l.get(1);//runtime error, since 42 can't be cast into a String
Run Code Online (Sandbox Code Playgroud)
b)
List<String> l=new ArrayList<String>();表示该变量l是一个字符串列表,并且只接受字符串值。将下面的代码会导致编译器错误:
List<String> l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//compiler error
l.add(new Date());//compiler error
Run Code Online (Sandbox Code Playgroud)
c)
List<String> l=new ArrayList<>();基本相同List<String> l=new ArrayList<String>();。菱形运算符<>只是意味着编译器应该清楚,这里使用的是哪种类型,这样程序员就可以偷懒,让编译器来完成工作。
p)
List<String>l = new ArrayList<String>();告诉编译器, l 是List类型。因此,如果您想为ArrayList变量 l分配 an ,这是允许的,然后如果您决定 aLinkedList更好,您仍然可以分配 aLinkedList并且它仍然可以工作,因为LinkedList和ArrayList都实现了接口List。所以以下代码将起作用:
List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();
//use the List l like nothing has changed. You just don't need to care.
Run Code Online (Sandbox Code Playgroud)
q)
ArrayList<String> l= new ArrayList<String>();意味着,变量l是 anArrayList并且永远不能是任何其他List实现(如 a LinkedList),因此您无法轻松更改实现。因此,以下代码将无法编译:
List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();//compiler error; now you need to change many parts of your code if you still want to change the type of l to a LinkedList
Run Code Online (Sandbox Code Playgroud)
因此通常p是更好的解决方案,因为您可以轻松更改代码。只有您需要调用不属于List接口的方法,例如方法ArrayList使用q可能需要它trimToSize方法。但这是一种非常罕见的情况。
概括:
在几乎所有情况下,使用p比使用q更好。
此外,在几乎所有情况下最好还是使用b或c ^比一。无论您使用b还是c都没有那么重要。c只是短了一点。
第1部分。
一种)
List l = new ArrayList<String>();b)
List<String> l = new ArrayList<String>();C)
List<String> l = new ArrayList<>();
b) 和 c) 之间没有区别。
但是 a) 声明l为原始类型。这是不鼓励的。使用时l,编译器不“知道”数组元素的类型:
第2部分。
p)
List<String>l = new ArrayList<String>();q)
ArrayList<String> l = new ArrayList<String>();
不同之处在于lp)中的类型表示它可以是任何List实现,但在 q) 中它仅限于ArrayList和 子类型。
如果l只在本地使用,它可能没什么区别。但是如果l是你的 API 的一部分,或者如果你需要分配l一个不同的List值,你可能会遇到问题。例如,当您调用List.sublistan 时ArrayList,您返回的对象不是ArrayList!
所以......作为一般规则,p) 更好。
一般来说,最好是“编程到接口”(即 p)而不是实现(即 q)。