List <! - ? - >在java泛型中意味着什么?

时间:2009-12-04 04:02:38

标签: java generics bounded-wildcard

List<?>是什么意思,它只是一个未指定类型的对象列表?

搜索字符串<?>不会返回任何有用的内容(:

11 个答案:

答案 0 :(得分:38)

正如Tom所说,?或无界通配符意味着未指定对象的类型。它可能是未知的,可能意味着多个可能的值,或者可能只是简单无关紧要。您的示例List<?>发音为“未知列表”。它很方便,因为它很灵活,但也存在一些陷阱,因为你无法将随机物品推入并将它们从未知组中拉出来而完全不受惩罚。

资源:

  • Java教程中讨论了通配符here
  • 有一个很好的 - 如果详细的 - 关于泛型的教程,一般由Angelika Langer提供here
  • Gilad Bracha还有另一个很好的概述here(PDF);请查看第5-7页。
  • 最后,如果你能够接受Josh Bloch的 Effective Java ,那么它就有了一个关于泛型的很棒的部分以及你能够,不能,应该和不应该使用的案例通配符(第5章,第二版第109-146页)。

顺便提一下,您的Google搜索失败是因为Google没有使用特殊字符进行加载:

  

除了一些例外情况,标点符号会被忽略(也就是说,您无法搜索@#$%^&amp; *()= + [] \和其他特殊字符。)

- Google help page

(编辑:我昨晚写这篇文章时一定很累。清理格式/添加一些信息。)

答案 1 :(得分:31)

获取更多信息所需的关键字是Wildcards

答案 2 :(得分:5)

要回答这个问题,我需要解释无界通配符和有界通配符 这篇文章的内容是从java文档中汇编而来的。

1。无界通配符

  

使用通配符(?)指定无界通配符类型,例如List<?>。这称为未知类型的列表。有两种情况,无界通配符是一种有用的方法:

     
      
  • 如果您正在编写可以使用Object类中提供的功能实现的方法。

  •   
  • 当代码使用泛型类中不依赖于类型参数的方法时。例如,List.sizeList.clear。事实上,Class<?>经常被使用,因为Class<T>中的大部分方法都不依赖于T

  •   

2。有界通配符

  

考虑一个简单的绘图应用程序,可以绘制矩形和圆形等形状。要在程序中表示这些形状,您可以定义类层次结构,例如:

public abstract class Shape {
    public abstract void draw(Canvas c);
}

public class Circle extends Shape {
    private int x, y, radius;
    public void draw(Canvas c) {
        ...
    }
}

public class Rectangle extends Shape {
    private int x, y, width, height;
    public void draw(Canvas c) {
        ...
    }
}
  

可以在画布上绘制这些类:

public class Canvas {
    public void draw(Shape s) {
        s.draw(this);
   }
}
  

任何绘图通常都包含许多形状。假设它们被表示为一个列表,在Canvas中有一个方法可以方便地绘制它们:

public void drawAll(List<Shape> shapes) {
    for (Shape s: shapes) {
        s.draw(this);
   }
}
  

现在,类型规则说drawAll()只能在精确形状的列表上调用:例如,它不能在List<Circle>上调用。这是不幸的,因为所有方法都是从列表中读取形状,所以它也可以在List<Circle>上调用。我们真正想要的是接受任何形状列表的方法:       public void drawAll(List shapes){           ...       }   这里有一个很小但非常重要的区别:我们已将List<Shape>替换为List<? extends Shape>。现在drawAll()将接受Shape的任何子类的列表,因此我们现在可以根据需要在List<Circle>上调用它。

     

List<? extends Shape>是有界通配符的示例。 ?代表一种未知类型,但在这种情况下,我们知道这种未知类型实际上是Shape的子类型。 (注意:它可能是Shape本身,或者是一些子类;它不需要字面上扩展Shape。)我们说Shape是通配符的上限

类似地,语法? super T是有界通配符,表示未知类型,它是T的超类型。 例如,ArrayedHeap280<? super Integer>包括ArrayedHeap280<Integer>ArrayedHeap280<Number>ArrayedHeap280<Object>。 正如您在java documentation for Integer class中看到的那样,Integer是Number的子类,而Number又是Object的子类。

答案 3 :(得分:4)

听起来你应该寻找一些关于Java泛型的文档。

List<?>表示它是基于当前未指定类型的对象。该类是在实例化类时生成的。

例如:

List<String> listOfStrings = new ArrayList<String>();

是String对象的列表。

答案 4 :(得分:3)

List是一个您可以自己实现的接口,也可以由某些Java集合实现,例如Vector

您可以使用有角度的括号提供编译时键入信息。最通用的类​​型是Object,即List<Object>。您看到的<?>表示ObjectObject的某个子类的列表。这就像说List<? extends Object>List<? extends Foo>,其中List包含某些Foo子类的对象或Foo本身的对象。

您无法实例化List;它是一个接口,而不是一个实现。

答案 5 :(得分:3)

  • create table MerchantConfig ( id bigint not null auto_increment, entityId bigint, entityType varchar(255) ) engine=InnoDB :完全没有类型限制和分配限制。
  • List:似乎与List<Object>相同,但是在接受其他通用分配时会出现编译错误。
  • List:这是一个通用类型。分配之前,这意味着它可以接受任何类型的集合分配,但是分配之后,您不能List<?>个元素,但是可以addremove,而不是{ {1}}。 clear通常用作接收外部集合或返回特定元素类型的集合的参数,也称为immutable set

测试代码和结果如下:

List<?>

结果是:

wildcard collection

答案 6 :(得分:2)

List<?>代表List<? extends Object>所以在Collection<E>您会找到允许您撰写的containsAll(Collection<?> c)

List<Object> objs = Arrays.<Object>asList("one",2,3.14,4);
List<Integer> ints = Arrays.asList(2,4);
assert objs.containsAll(ints);//true

答案 7 :(得分:0)

从集合中取出元素时,必须将其强制转换为集合中存储的元素类型。除了不方便之外,这是不安全的。编译器不会检查您的强制转换是否与集合的类型相同,因此强制转换可能会在运行时失败。

泛型提供了一种将集合类型传递给编译器的方法,以便可以检查它。一旦编译器知道集合的元素类型,编译器就可以检查您是否一直使用了集合,并且可以在从集合中取出的值上插入正确的强制转换。

chk dis pdf

答案 8 :(得分:0)

?只是泛型中的通配符

泛型中有3种不同的通配符

1)上界通配符:使用扩展关键字

eg: List<? extends SuperClass>

2)下界通配符

eg:Uses Super key word List<? super SubClass>

3)无界通配符

List<?> list

答案 9 :(得分:0)

List 等价于 List

<块引用>

通配符? extends Object 等价于无界通配符?

<?> 在 Java 规范中

Generics 在 Java 规范中

答案 10 :(得分:-1)

您可能正在查看基于List类的模板。您可以按List<String> myList = new MyList<String>();创建字符串列表作为示例。检查文档中是否支持所有类型。它应该支持任何对象类型,但如果有排序功能,则必须提供一些比较函数。

请注意,在上面的示例中,MyList是一个在Java中实现List接口的具体类。它可以是ArrayList

编辑: 我错误地认为List是一个具体的类。修正了上面的错误。谢谢Jon。