Kon*_*lph 18

这意味着您正在处理具有类型的项目集合E.想象一下,你喝了一杯茶.它也可以装咖啡,而不是茶,所以将杯子描述为通用实体是有意义的:

class Cup<T> { … }
Run Code Online (Sandbox Code Playgroud)

现在你可以用咖啡或茶(或其他东西)填充它:

Cup<Tea> cuppa = new Cup<Tea>();
Cup<Coffee> foamee = new Cup<Coffee>();
Run Code Online (Sandbox Code Playgroud)

为了这个工作,既TeaCoffee将需要在你的程序中定义以及类型.

这是对代码的编译时约束.从(相当无用的)杯子示例回来,集合(数组,列表......)通常包含一种类型的项目,例如整数或字符串.泛型帮助您在Java中表达这一点:

Collection<String> strList = new ArrayList<String>();
strList.add("Foobar"); // Works.
strList.add(42);       // Compile error!
Run Code Online (Sandbox Code Playgroud)

注意上面的编译错误?你只有在使用泛型时才会得到这个.以下代码也有效,但不会给出错误消息:

Collection strList = new ArrayList();
strList.add("Foobar"); // Works.
strList.add(42);       // Works now. Do we really want this?!
Run Code Online (Sandbox Code Playgroud)

  • 作为班级杯<T>的混乱实际上会被宣布为一杯T :) (2认同)

Vin*_*vic 15

这是泛型的使用.检查此介绍.然后不要忘记阅读本教程.

摘录如下(比较演员与使用仿制品的比较):

当您看到代码<Type>时,请将其读作"Type"; 上面的声明读作"字符串集合c."使用泛型的代码更清晰,更安全.我们已经消除了一个不安全的演员阵容和一些额外的括号.更重要的是,我们已将方法的部分规范从注释移动到其签名,因此编译器可以在编译时验证在运行时不违反类型约束.因为程序在没有警告的情况下编译,我们可以肯定地说它不会在运行时抛出ClassCastException.使用泛型的净效果,特别是在大型程序中,是提高了可读性和稳健性.

例如,List的接口是

public interface List<E> { 
    void add(E x);
    Iterator<E> iterator();
}
Run Code Online (Sandbox Code Playgroud)

这意味着您可以构建一个列表,其内容都是相同的显式类型(不仅是Object类型),即使您自己定义了类型.因此,如果您创建一个Name类,您可以编写

List<Name> nameList = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

然后用Name实例填充它并直接从它中检索Name实例,而不必抛出或担心它,因为你总是得到一个Name实例或null返回,而不是一个不同类型的实例.

更重要的是,您不能在这样的List中插入与Name实例不同的任何内容,因为它在编译时会失败.

nameList.add(false); //Fails!
nameList.add(new Name("John","Smith")); //Succeeds supposing Name has a 
                                        //firstName, lastName constructor
Run Code Online (Sandbox Code Playgroud)