我正在尝试建立我的Java入门知识,并且我正在拓展数据结构。
我正在查看ArrayList
,而我并不理解以下内容:
List<String> myList = new ArrayList<String>();
我用Google搜索了type parameter
但我并不真正理解为什么它是必要的以及它做了什么(对于构造函数的调用和初始化变量);如果有人能用简单的方式向我解释,那就太好了。
谢谢
答案 0 :(得分:6)
首先,我强烈建议您阅读Java generics tutorial。
其次,简单回答你的问题。通过使用这样的泛型类型,您强制编译器使用此实例对代码使用强类型检查。
如果您将列表定义为:
List myList = new ArrayList();
您可以向其中添加任何类型的对象,例如:
myList.add(new Integer());
myList.add(new Long());
通过将列表声明为:
List<String> myList = new ArrayList<String>();
你告诉编译器这个列表只接受字符串,所以:
myList.add(new Integer());
会抛出编译时错误。
答案 1 :(得分:1)
在Java 7中,您可以使用Diamond运算符(将其视为反向类型推断,如果有帮助的话),所以:
List<String> myList = new ArrayList<>();
这意味着您只能向此列表添加类String
的子对象或String
的子类。
泛型通常对于Interfaces比Concrete类更有用。
答案 2 :(得分:0)
case中的type参数String表示ArrayList只能包含String,不允许其他类型。它也有助于从ArrayList中检索值时,您将确保输出是String并且可以直接分配给String。
答案 3 :(得分:0)
使用此声明,您只需设置ArrayList的数据类型。这样就可以确保ArrayList是一个字符串数组
答案 4 :(得分:0)
要理解这一点,您需要了解泛型如何在java中工作。简而言之,该类型允许Generic ArrayList将每个元素强制转换为类型,并将每个对象作为类型返回。
实施看起来像这样
public class ArrayList<T>{
public void add(T element)
public <T> get()
}
在您的示例中,这允许您将数组列表与字符串
一起使用在后台,对象仍然是对象,但每次读/写访问都是castet。
所以你有类似安全的东西(可以打破as you can read here)。
答案 5 :(得分:0)
泛型告诉编译器,ArrayList只能包含String对象。
答案 6 :(得分:0)
这是 Generics 的一个例子,但是有一段时间你可以在不知道泛型的血腥细节的情况下离开 - 教程会告诉你如何编写像ArrayList
这样的类;现在你只需要知道如何使用它。
在Generics之前,你会声明一个像这样的List:
List l = new ArrayList();
...并且List包含一组对象。 Java运行时不关心你放入什么样的对象。
l.add(new Integer(3);
l.add("A String");
...并且Java运行时无法告诉你你得到的对象是什么类型,所以你必须把它投出来:
String s = (String) l.get(1); // throws a ClassCastException if object is not a String
这意味着编译器可以检测到可以检测到的各种编程错误,只要语言能够更好地表达自己,只能在运行时捕获。
所以,相反,让我们添加一些说明List包含的内容:
List<String> l = new ArrayList<String>();
这意味着您只能add()
列表中的字符串,而列表中get()
的任何内容都是字符串:
l.add(new Integer(1)); // compile error -- incompatible types
l.add("Hello"); // works
String s = l.get(0); // works, without casting
它适用于多态。因此,如果Apple
和Banana
是Fruit
的子类:
List<Fruit> fruitList = new ArrayList<Fruit>();
fruitList.add(new Apple());
fruitList.add(new Banana());
如果您查看List
的JavaDoc,您会看到它被记录为List<E>
- 其中E
是占位符,表示您在声明变量时插入的任何类型
方法以相同的方式记录:boolean add(E e)
,E get(int index)
,等等。
答案 7 :(得分:0)
仿制药的主要用途是提供类型安全性。如果不使用泛型,则对象将作为对象类型的引用出现。在泛型之前,没有办法声明arraylist的类型,所以它的add()方法默认采用了type对象。
简单来说,例如。了解泛型如下
ArrayList<String> l=new ArrayList<String>();
l.add(null); // It will add type of string
在这里,使用泛型,您现在只能将字符串对象放在ArrayList中,并且对象将作为字符串类型的引用出现。
简而言之,使用泛型,您可以创建类型安全的集合,在编译时捕获更多问题而不是运行时