2011-05-19 63 views
5

的重载函数compute1()compute2(),并且compute5()导致编译错误,如果你尝试下面使用它们:的Java:编译时间分辨率和“最具体的方法”

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阶段(允许装箱/取消装箱,没有可变参数)匹配重载方法时,JLS说(实际上)最具体的方法是形式参数是其他适用方法的子类型,并且基元和对象(例如,intInteger)不是彼此的子类型。所以IntegerInteger一个亚型,和intint一个亚型,但Integerint是不相容的W/R /吨亚型的比较,所以既不compute1() /compute2()对具有最特定的方法。

(而在compute3()compute4()方法与String说法是不是与Object参数的方法更具体,所以程序将打印6,8)

是我的推理是否正确?

回答

0

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

+0

接受,但我希望看到一些额外的启示。 – 2011-06-08 13:32:06

0

如果添加另一个刚是一个原始int和装箱的整数方法,它能够解决哪一个是正确的方法来调用:在此基础上

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

,我会想象它与不同参数之间的交互有关,而不仅仅是单独的类型关系。

+2

不,在你的例子中,compute6(int)首先匹配,因为JLS指定应该首先找到方法而不尝试使用自动装箱/拆箱,这是一个不同的问题。 (是的,这是令人困惑的,最后,没有简单直观的方式来管理边缘案例;你只需要通过JLS作为明确的答案。) – 2011-05-19 17:22:48

+0

啊,有趣。不知道。 – 2011-05-20 19:41:49