public void demo(Object value){}
public void demo(List<Objcet> value){}
针对上面这种情况,什么时候会访问 List<Object>
这个参数的接口,或者说怎么访问第二种方式的接口?
我试了下 List<String> params;
,把 params 传入会进入第一个接口。
1
crayygy 2018-12-25 15:13:54 +08:00 via Android 1
Effective Java 中有提过这个。
原因是 List 本身也是 Object。 至于怎么访问,更好做法是不要这么写 |
2
SilentHill 2018-12-25 15:18:09 +08:00 2
params 类型改为 List<Object>
或者 params 类型强转为(List)params |
3
aaronysj 2018-12-25 15:25:04 +08:00
试了一下,你直接传 params 的话,自然会被当成一个 Object。
但传入 (List)params 会走一道强制转换,这个过程似乎编译器会认为它是个 List,就会进入第二种方式了,但这样写似乎有些奇怪。 我试了下 Arrays.asList()这类的方法,也是可以进入第二种方式的,因为此类方法返回值类型限制了。 但还是同一楼一样,觉得没必要这样写。 |
4
ukipoi OP |
6
letianqiu 2018-12-25 16:45:40 +08:00 1
Java 的 Generic 存在 type erasure,所以 List<String>不是 List<Object>的字类。我没记错的话 params 类型写成 List<?>可以
|
7
codechaser 2018-12-25 16:53:20 +08:00 via Android
类型擦除后会都变为 list,这个问题我也不懂,都擦除成了 list<object>,怎么不能用第二种呢?求解释
|
8
yhvictor 2018-12-25 17:00:09 +08:00
Java 中函数调用都是编译时确定的,编译的时候会看哪个更匹配用哪个。
编译的后就擦除了信息。 如果编译器不能分辨出应该用哪个,会编译失败。 |
9
feiyuanqiu 2018-12-25 17:19:02 +08:00 via Android 2
因为类型擦除,List<String> 不是 List<Object> 的子类,它的父类是 Object,所以调用了第一个方法;要调用第二个方法,要么传入 List<Object>,要么改方法签名。
https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html 关于 Overloading,可以看看 R 大在知乎这个回答( ps. R 大的每个回答都值得 Java 开发者一看) https://www.zhihu.com/question/50111592/answer/119694222 |