Java ,请教一下重载的问题。

2018-12-25 15:05:29 +08:00
 ukipoi
public void demo(Object value){}
public void demo(List<Objcet> value){}

针对上面这种情况,什么时候会访问 List<Object> 这个参数的接口,或者说怎么访问第二种方式的接口?
我试了下 List<String> params; ,把 params 传入会进入第一个接口。

2435 次点击
所在节点    Java
9 条回复
crayygy
2018-12-25 15:13:54 +08:00
Effective Java 中有提过这个。
原因是 List 本身也是 Object。

至于怎么访问,更好做法是不要这么写
SilentHill
2018-12-25 15:18:09 +08:00
params 类型改为 List<Object>
或者 params 类型强转为(List)params
aaronysj
2018-12-25 15:25:04 +08:00
试了一下,你直接传 params 的话,自然会被当成一个 Object。
但传入 (List)params 会走一道强制转换,这个过程似乎编译器会认为它是个 List,就会进入第二种方式了,但这样写似乎有些奇怪。
我试了下 Arrays.asList()这类的方法,也是可以进入第二种方式的,因为此类方法返回值类型限制了。
但还是同一楼一样,觉得没必要这样写。
ukipoi
2018-12-25 15:34:51 +08:00
@aaronysj
嗯,我是在看别人写的 Redis 操作类的时候看到的代码。我发现直接传入会出问题。
同时我想请教下 JPA MySQL 以及 Redis 在 Spring 下是怎样运作的。
之前是使用 Mybatis 和 Redis,其实原理也不是很懂。但是好像加上 @Cache 的注解就会进入缓存了。
那么在使用 JPA 的情况下是需要重写 Repository 里的操作手动的存入 Redis 缓存,还是执行 save 方法的时候会自动缓存呢?或者有其他更好的方法?
aaronysj
2018-12-25 15:42:53 +08:00
@ukipoi 我是渣渣,问下 google 呢 ///溜了
letianqiu
2018-12-25 16:45:40 +08:00
Java 的 Generic 存在 type erasure,所以 List<String>不是 List<Object>的字类。我没记错的话 params 类型写成 List<?>可以
codechaser
2018-12-25 16:53:20 +08:00
类型擦除后会都变为 list,这个问题我也不懂,都擦除成了 list<object>,怎么不能用第二种呢?求解释
yhvictor
2018-12-25 17:00:09 +08:00
Java 中函数调用都是编译时确定的,编译的时候会看哪个更匹配用哪个。
编译的后就擦除了信息。
如果编译器不能分辨出应该用哪个,会编译失败。
feiyuanqiu
2018-12-25 17:19:02 +08:00
因为类型擦除,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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/520837

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX