【问题标题】:Will library overloaded method be used without recompiling?是否会在不重新编译的情况下使用库重载方法?
【发布时间】:2011-05-24 17:59:48
【问题描述】:

说库里有方法

public static <E> void doSmth(Collection<E> foo, Collection<E> bar){...}

并在以下代码中使用:

Set<Object> foo = ...;
List<Object> bar = ...;
doSmth(foo, bar);

现在另一个版本的库在类路径中替换了前者,它有两种方法:

public static <E> void doSmth(Collection<E> foo, Collecion<E> bar){...}
public static <E> void doSmth(Set<E> foo, List<E> bar){...}

应用程序没有重新编译和运行。将使用哪种方法?

【问题讨论】:

    标签: java classloader overloading


    【解决方案1】:

    重载解析是一个编译时过程,因此如果不重新编译,其结果不会改变。

    所以,

    public static <E> void doSmth(Collection<E> foo, Collecion<E> bar){...}
    

    将被使用,因为它的签名是在编译文件中指定的。

    【讨论】:

    • java.sun.com/docs/books/jls/third_edition/html/… - 是否仅适用于静态方法而不适用于实例方法?
    • @Ivan:重载解析以相同的方式应用于静态和实例方法。如果您指的是该部分的最后一行,则涉及重写其签名被重载决议选择的方法的情况。
    【解决方案2】:

    如果您在类路径中有同一个库的 2 个版本,则很难判断类加载器会首先加载哪个版本(因此会使用哪个版本)——事实上,不同机器和 JVM 的结果可能会有所不同到 JVM。 如果确实需要先加载某个版本,可以通过命令行中的-Xbootclasspath参数将其添加到bootclasspath

    【讨论】:

    • 不,类路径中只有一个版本的库。首先 - 在编译和首次运行期间。第二 - 在第二次运行期间。
    • 那么第二版的库只有在第二次运行后才会出现?如何? :O
    【解决方案3】:

    库不包含方法,类包含。并且类在第一次需要时由类加载器加载。

    类(通常)按照它们在类路径中出现的顺序加载。 通常只是因为花哨的自定义类加载器可以实现其他策略。

    所以对于你的问题,看看正常行为:如果我们在路径上有两个同名的,一个包含两个,另一个包含一个方法,然后只加载一个类,即类加载器首先找到的类。一旦加载了一个类,(同一个)类加载器就不需要再次寻找同名的类了。


    Overloading is determined statically at compile time, so method 1 will (still) be called.

    【讨论】:

    • 对于“类路径中出现另一个版本的库”这句话,我感到非常抱歉。我不是这个意思。
    • @Ivan - 得到它并增强了答案;)
    猜你喜欢
    • 2011-04-07
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 2013-12-02
    • 2014-01-28
    • 1970-01-01
    相关资源
    最近更新 更多