简体   繁体   English

Java:编译时解析和“最具体的方法”

[英]Java: compile-time resolution and “most specific method”

The overloaded functions compute1() , compute2() , and compute5() cause compilation errors if you try to use them below: 如果您尝试在下面使用它们,重载函数compute1()compute2()compute5()会导致编译错误:

package com.example.test.reflect;

class JLS15Test2
{
    int compute1(Object o1, Integer i, Integer j)         { return 1; }
    int compute1(String s1, Integer i, int j)             { return 2; }

    int compute2(Object o1, Integer i, int j)             { return 3; }
    int compute2(String s1, Integer i, Integer j)         { return 4; }

    int compute3(Object o1, Integer i, int j)             { return 5; }
    int compute3(String s1, Integer i, int j)             { return 6; }

    int compute4(Object o1, Integer i, Integer j)         { return 7; }
    int compute4(String s1, Integer i, Integer j)         { return 8; }

    int compute5(Object o1, Integer i, Object j)          { return 9; }
    int compute5(String s1, Integer i, int j)             { return 10; }


    public static void main(String[] args) 
    {
        JLS15Test2 y = new JLS15Test2();

        // won't compile:
        // The method compute1(Object, Integer, Integer) is ambiguous 
        // for the type JLS15Test2
        // System.out.println(y.compute1("hi", 1, 1));

        // Neither will this (same reason)
        // System.out.println(y.compute2("hi", 1, 1));
        System.out.println(y.compute3("hi", 1, 1));
        System.out.println(y.compute4("hi", 1, 1));

        // neither will this (same reason)
        // System.out.println(y.compute5("hi", 1, 1));
    }
}

After reading the JLS section 15.12, I think I understand... in phase 2 (boxing/unboxing allowed, no varargs) of matching overloaded methods, when determining the "most specific method", the JLS says (in effect) that the most specific method is the one whose formal parameters are subtypes of other applicable methods, and primitives and Objects (eg int and Integer ) are never subtypes of each other. 在阅读JLS第15.12节之后,我想我理解......在第2阶段(装箱/取消装箱允许,没有varargs)匹配重载方法,在确定“最具体的方法”时,JLS说(实际上)最多特定方法是其形式参数是其他适用方法的子类型的方法,而原语和对象(例如intInteger )从不是彼此的子类型。 So Integer is a subtype of Integer , and int is a subtype of int , but Integer and int are incompatible w/r/t subtype comparisons, so neither of the compute1() / compute2() pairs have a most specific method. 所以Integer是的子类型Integer ,和int是的子类型int ,但Integerint是不相容的W / R /吨亚型的比较,所以既不的compute1() / compute2()对具有最特定的方法。

(Whereas in compute3() and compute4() the method with the String argument is more specific than the method with the Object argument, so the program prints 6 and 8.) (在compute3()compute4() ,使用String参数的方法比使用Object参数的方法更具体,因此程序打印6和8.)

Is my reasoning correct? 我的推理是否正确?

是的,你的推理是正确的。

If you add another method that just takes a primitive int and a boxed Integer, it is able to resolve which one is the proper method to called: 如果你添加另一个只接受一个原始int和一个盒装Integer的方法,它就能解析哪一个是正确的调用方法:

int compute6(int i) { return 11;}
int compute6(Integer i){return 12;}
...
System.out.println(y.compute6(1));

Based on that, I'd imagine that it has something to do with the interaction between the different parameters, and not just the separate type relationships. 基于此,我认为它与不同参数之间的交互有关,而不仅仅是单独的类型关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM