V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ukipoi
V2EX  ›  Java

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

  •  
  •   ukipoi · 2018-12-25 15:05:29 +08:00 · 2448 次点击
    这是一个创建于 2171 天前的主题,其中的信息可能已经有所发展或是发生改变。
    public void demo(Object value){}
    public void demo(List<Objcet> value){}
    

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

    9 条回复    2018-12-25 17:19:02 +08:00
    crayygy
        1
    crayygy  
       2018-12-25 15:13:54 +08:00 via Android   ❤️ 1
    Effective Java 中有提过这个。
    原因是 List 本身也是 Object。

    至于怎么访问,更好做法是不要这么写
    SilentHill
        2
    SilentHill  
       2018-12-25 15:18:09 +08:00   ❤️ 2
    params 类型改为 List<Object>
    或者 params 类型强转为(List)params
    aaronysj
        3
    aaronysj  
       2018-12-25 15:25:04 +08:00
    试了一下,你直接传 params 的话,自然会被当成一个 Object。
    但传入 (List)params 会走一道强制转换,这个过程似乎编译器会认为它是个 List,就会进入第二种方式了,但这样写似乎有些奇怪。
    我试了下 Arrays.asList()这类的方法,也是可以进入第二种方式的,因为此类方法返回值类型限制了。
    但还是同一楼一样,觉得没必要这样写。
    ukipoi
        4
    ukipoi  
    OP
       2018-12-25 15:34:51 +08:00
    @aaronysj
    嗯,我是在看别人写的 Redis 操作类的时候看到的代码。我发现直接传入会出问题。
    同时我想请教下 JPA MySQL 以及 Redis 在 Spring 下是怎样运作的。
    之前是使用 Mybatis 和 Redis,其实原理也不是很懂。但是好像加上 @Cache 的注解就会进入缓存了。
    那么在使用 JPA 的情况下是需要重写 Repository 里的操作手动的存入 Redis 缓存,还是执行 save 方法的时候会自动缓存呢?或者有其他更好的方法?
    aaronysj
        5
    aaronysj  
       2018-12-25 15:42:53 +08:00
    @ukipoi 我是渣渣,问下 google 呢 ///溜了
    letianqiu
        6
    letianqiu  
       2018-12-25 16:45:40 +08:00   ❤️ 1
    Java 的 Generic 存在 type erasure,所以 List<String>不是 List<Object>的字类。我没记错的话 params 类型写成 List<?>可以
    codechaser
        7
    codechaser  
       2018-12-25 16:53:20 +08:00 via Android
    类型擦除后会都变为 list,这个问题我也不懂,都擦除成了 list<object>,怎么不能用第二种呢?求解释
    yhvictor
        8
    yhvictor  
       2018-12-25 17:00:09 +08:00
    Java 中函数调用都是编译时确定的,编译的时候会看哪个更匹配用哪个。
    编译的后就擦除了信息。
    如果编译器不能分辨出应该用哪个,会编译失败。
    feiyuanqiu
        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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5972 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 01:57 · PVG 09:57 · LAX 17:57 · JFK 20:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.