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

时间:2011-05-19 16:48:30

标签: java language-lawyer jls subtype

如果您尝试在下面使用它们,重载的函数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));
    }
}

在阅读JLS第15.12节之后,我想我理解......在第2阶段(装箱/取消装箱允许,没有varargs)匹配重载方法时,在确定“最具体的方法”时,JLS说(实际上)最具体的方法是其形式参数是其他适用方法的子类型的方法,而基元和对象(例如intInteger)绝不是彼此的子类型。因此IntegerInteger的子类型,而int是[{1}}的子类型,但intInteger不相容w / r / t子类型比较,因此int / compute1()对都没有最具体的方法。

(在compute2()compute3()中,compute4()参数的方法比具有String参数的方法更具体,因此程序打印6和8。 )

我的推理是否正确?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

如果添加另一个只接受原始int和盒装Integer的方法,它可以解析哪一个是调用的正确方法:

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

基于此,我认为它与不同参数之间的相互作用有关,而不仅仅是单独的类型关系。