Java 泛型 -- 依据声明的变量类型自动推断

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 来调用。

下面以一张图来呈现不用调用方式时推断出的类型

java_generic_auto_infer

依各行代码行简要说明

行 5:    泛型方法中,什么也不知道,只是 T
行 9:    因为方法  foo() 声明的类型是 String, 所以 return abc() 时应用的具体类型就是 String
行 13:  声明的类型  ss 是 Integer, 因而应用 Integer  具体类型
行 16:  没有类型信息所以当作 Object 来处理
行 19:  String 类型是为 abc() 结果值的方法调用的返回值定义的,所以只认为 abc() 得到的是一个 Object


如果不能用声明的类型来指示,还可以通过方法参数来传达类型信息,如

abc(...) 返回值就直接知道是相应的具体类型了。

小结:

三种方式告诉泛型方法具体化的类型

1. 显式的写在 <> 号,如 new ArrayList<String> 或 Test.<String>foo()
2. 声明类型,如 String s = Test.foo()
3. 方法参数, 如 Test.foo(String.class) 或 Test.foo("abc")

本文链接 https://yanbin.blog/java-generic-auto-infer-by-declare-type/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

1 Comment
Inline Feedbacks
View all comments
香港云主机
9 years ago

亲,2015新年发福利啰,独立ip主机限时抢啦