Java 泛型在调用方法操作时应用具体参数还是很好理解的,比如
Map<String, Integer> map = new HashMap<>(); //钻石操作符是 JDK 1.7 引入的
后续的 put 操作调用的具体方法就是
Integer put(String key, Integer value)
因为 put 方法的原型是
V put(K key, V value)
上面的代码我们是看到了 <>,所以知道是泛型调用。有时候并不需要 <>,但实际上也是进行的泛型调用,那就是 Java 可以依据变量声明类型来作特化调用 -- 应用具体参数类型。
例如:
List<String> list = Collections.emptyList(); //虽不见 <>, 但同样是泛型调用,类型为 String
它调用的方法的实现代码是
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
Collections.emptyList() 调用时根据声明的 List<String> 自动具体化类型为 String 来调用。
下面以一张图来呈现不用调用方式时推断出的类型
依各行代码行简要说明
行 5: 泛型方法中,什么也不知道,只是 T
行 9: 因为方法 foo() 声明的类型是 String, 所以 return abc() 时应用的具体类型就是 String
行 13: 声明的类型 ss 是 Integer, 因而应用 Integer 具体类型
行 16: 没有类型信息所以当作 Object 来处理
行 19: String 类型是为 abc() 结果值的方法调用的返回值定义的,所以只认为 abc() 得到的是一个 Object
如果不能用声明的类型来指示,还可以通过方法参数来传达类型信息,如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Test { static <T> T abc(Class<T> type) { return (T) "abc"; } static <T> T abc(T t) { return (T) "abc"; } public static void main(String[] args) { abc(String.class).toCharArray(); abc("123").toLowerCase(); } } |
abc(...) 返回值就直接知道是相应的具体类型了。
小结:
三种方式告诉泛型方法具体化的类型
1. 显式的写在 <> 号,如 new ArrayList<String> 或 Test.<String>foo()
2. 声明类型,如 String s = Test.foo()
3. 方法参数, 如 Test.foo(String.class) 或 Test.foo("abc")
亲,2015新年发福利啰,独立ip主机限时抢啦