2013-10-13 58 views

回答

6

类实际上没有原始类型,它被称为unknown typeunbounded wildcard

从Java文档:

无界通配符

The unbounded wildcard type is specified using the wildcard character (?), for example, List<?>. This is called a list of unknown type. There are two scenarios where an unbounded wildcard is a useful approach:

If you are writing a method that can be implemented using functionality provided in the Object class. When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In fact, Class<?> is so often used because most of the methods in Class<T> do not depend on T.

1

的无界通配符<?>似乎意味着 “任何东西”,因此使用无界通配符似乎等同于使用原始类型。事实上,编译器似乎在第一次进行这种评估同意:

import java.util.ArrayList; 
import java.util.List; 

public class UnboundedWildcards1 { 
    static List list1; 
    static List<?> list2; 
    static List<? extends Object> list3; 

    static void assign1(List list) { 
     list1 = list; 
     list2 = list; 
     // list3 = list; // Warning: unchecked conversion 
     // Found: List, Required: List<? extends Object> 
    } 

    static void assign2(List<?> list) { 
     list1 = list; 
     list2 = list; 
     list3 = list; 
    } 

    static void assign3(List<? extends Object> list) { 
     list1 = list; 
     list2 = list; 
     list3 = list; 
    } 

    public static void main(String[] args) { 
     assign1(new ArrayList()); 
     assign2(new ArrayList()); 
     // assign3(new ArrayList()); // Warning: 
     // Unchecked conversion. Found: ArrayList 
     // Required: List<? extends Object> 
     assign1(new ArrayList<String>()); 
     assign2(new ArrayList<String>()); 
     assign3(new ArrayList<String>()); 
     // Both forms are acceptable as List<?>: 
     List<?> wildList = new ArrayList(); 
     wildList = new ArrayList<String>(); 
     assign1(wildList); 
     assign2(wildList); 
     assign3(wildList); 
    } 
} 

有很多情况下,像你在这里看到的那些,你是否使用原始类型或<编译器可以不在乎? >。在这些情况下,<? >可以被认为是一种装饰;但它很有价值,因为实际上它说:“我在脑海中编写了带有Java泛型的代码,我并不是说我在使用原始类型,但在这种情况下泛型参数可以保持任何类型“。

第二个示例显示了未绑定通配符的重要用法。当你正在处理多个通用的参数,它允许一个参数是任何类型的,而对于其他参数建立一个特定类型的有时非常重要:再次

import java.util.HashMap; 
import java.util.Map; 

public class UnboundedWildcards2 { 
    static Map map1; 
    static Map<?, ?> map2; 
    static Map<String, ?> map3; 

    static void assign1(Map map) { 
     map1 = map; 
    } 

    static void assign2(Map<?, ?> map) { 
     map2 = map; 
    } 

    static void assign3(Map<String, ?> map) { 
     map3 = map; 
    } 

    public static void main(String[] args) { 
     assign1(new HashMap()); 
     assign2(new HashMap()); 
     // assign3(new HashMap()); // Warning: 
     // Unchecked conversion. Found: HashMap 
     // Required: Map<String,?> 
     assign1(new HashMap<String, Integer>()); 
     assign2(new HashMap<String, Integer>()); 
     assign3(new HashMap<String, Integer>()); 
    } 
} 

但是,当你把所有无界通配符,如在地图<?,?>,编译器似乎没有区别它与原始的地图。另外,第一个例子显示编译器对待列表<?>列表<?以不同方式扩展对象>

欲了解更多信息,欢迎您阅读布鲁斯埃克尔的书:Thinking in Java

相关问题