关于这道题,JLS2中看到有这么一句:"The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error." 英文不好,哪位给精确翻译一下?

解决方案 »

  1.   

    class Tester

      void test(Object s)
      {
        System.out.println ("Object version");
      } 
      /*void test(Tester s)
      {
        System.out.println ("Tester version");
      } */
      void test(String s){System.out.println("String version");}   public static void main (String args[])
      { 
        Tester c = new Tester(); 
        c.test (null);
        c.test (new Object()); 
      } 

    这样写也是正确的,关键之处好象在于:编译器把null解释成为什么类型。
    希望高手指点。
      

  2.   

    如果把我的例子中4void test()方法全部写出来,编译就部通过,提示c.test(null);错误
    高手来看看啊
      

  3.   

    public class Tester {  public Tester() {
              System.out.println("Constructor Tester");
      }
      public void test(String s){
              System.out.println("Object verson:"+s);
      }
      public void test(Tester s){
              System.out.println("Tester verson:"+s);
      }
      public void test(SubTester s) {
               System.out.println("SubTester verson:"+s);
      }
      public void test(sonST s) {
               System.out.println("sonST verson:"+s);
      }
      public static void main(String[] args) {
        Tester c = new Tester();
        System.out.println("----------------------");
        c.test(null);
        System.out.println("----------------------");
        c.test(null);
      }
    }
    class SubTester extends Tester
    {
          public SubTester() {
                  System.out.println("Constructor SubTester");
          }
    }
    class sonST extends SubTester
    {
          public sonST() {
                  System.out.println("Constructor sonST");
          }
    }
      

  4.   

    楼上的,不是叫你改程序,而且你的程序也是错的。而是问问为什么
    1.第一次看到null也可以做为参数传递,那么c.test(null)到底指向哪个对应的test()方法啊?
    2.那行被注释掉的语句看到了吗?如果把注释去掉,那么整个程序编译就无法通过:错误信息很简单,就一句:一个错误在c.test(null);
    3. 这道题用到了哪些知识点啊?
      

  5.   

    译文:方法定义得越详细,即第一个方法的参数可以用来调用第2个方法而不引起便宜时错误,则带有null的方法调用将调用第一个方法。
    解释清楚了吗?
      

  6.   

    我们知道,在java里类都是引用类型,null就是空引用类型,它可以代表任何类(只不过它是空的)。在做匹配时,根据面向对象的基本原理,应该找一个与他最匹配的参数,即:
    A<-B<-C
    null将与C匹配。
    因为有:Object<-Tester<-SubTester,所以没有String时null将与SubTester匹配。
    而加上String后编译器无法决定调用那个函数所以出错。
      

  7.   

    注释去掉无法编译的原因是:
    test(SubTester),的参数无法用来调用test(String)或相反
    所以test(null)不知道调用那个方法,不过如果程序中没有test(null)将不会出错
      

  8.   

    1.第一次看到null也可以做为参数传递,那么c.test(null)到底指向哪个对应的test()方法啊?
    指向所能适应的最窄的(比如 参数是1,方法有参数类型int,float,它就会调int的),所以在本例中,它是指向public void test(SubTester s) 
    2、因为null可是任意对象类型的,所以JVM可以认为它是SubTester类型的,也可以是String类型的,主要到这两者不同于Tester和SubTester(他们是相容的),这时就产生了二义性错误!(不是什么 错误信息很简单,就一句:一个错误在c.test(null);试那里有二义性错误)
    3、Java的方法重载。
      

  9.   

    楼上两位:
    你们说:根据面向对象的基本原理,应该找一个与他最匹配的参数,即:A<-B<-C,null将与C匹配。我不太明白,为什么null要与类体系的最低级匹配啊(我这样理解对吗?)。而且,加了void test(String s)后,为什么就无法确定调用哪个函数了呢?
      

  10.   

    当然调用最特殊的(参数最详细)的方法,就像你去找人,知道门牌号还会到整条大街上去喊吗?
    test(SubTester)的参数无法用来调用test(String)或相反所以参数间的详细程度无法比较
    所以test(null)不知道调用那个方法,不过如果程序中没有test(null)将不会出错 
      

  11.   

    哦,基本明白了。
    我总结一下,你们看对不对:
      c.test(null)会和所有重载的void test()方法中参数类型最最详细的那个,也就是类体系中最低级的那个匹配。OK,我这还有个疑问:为什么JVM会搞不清void test(Sting s)和void test(SubTester s)到底哪个更加详细或低级呢?怎么对这种情况进行比较?
      

  12.   

    "The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error." 
    英文不佳,只可意会
    一个不太正规的观点是如果一个方法的声明所调用的(参数)可以传递给另一个方法而不会产生编译期错误,则(使用)第一个方法(比另一个)更准确。
    注:这也是第一行输出SubTester version的原因,因为null可以是任何类型传递给test(),但方法test(SubTester s)中的s可以传递给其它两个方法而不会出现编译期错误,当然反过来说则不行,所以认为test(SubTester s)更准确,输出的结果也证明了这一点。至于注释掉的那一句,前面的几位大虾已经解释得很清楚的了。
      

  13.   

    String 和 SubTester 没有继承关系,所以无法比较哪个更详细
      

  14.   

    to Patrick_DK(疾风摩郎),
    因为String和SubTester之间不存在任何的层次关系
    你能判断出到底哪个更加详细或低级吗?
      

  15.   

    呵呵,我不能。
    OK,做最后的“结案陈词”:    c.test(null)会和所有重载的void test()方法中参数类型最最详细的那个,也就是类体系中最低级的那个匹配。各位高手看一下,如果我的认识没有问题的话就给分了。
      

  16.   

    不完整。
    在重载方法中参数有可能混淆的情况下,编译器使用下面的策略:
    1. 如果发生混淆的位置上的所有参数类型在继承关系上构成一棵有分支的树,报错。
    2. 如果这些参数类型在继承关系上是一个队列,匹配类体系中最低级的那个。程序:
    public class InheritanceTest
    {
    public class C_1 extends Object {}

    public class C_1_1 extends C_1 {}
    public class C_1_2 extends C_1 {}

    public class C_1_1_1 extends C_1_1 {}
    public class C_1_1_2 extends C_1_1 {}
    public class C_1_2_1 extends C_1_2 {}

    public void pr( C_1 c )
    {
    System.out.println( "C_1" );
    }

    public void pr( C_1_1 c )
    {
    System.out.println( "C_1_1" );
    } public void pr( C_1_1_1 c )
    {
    System.out.println( "C_1_1_1" );
    } //报错
    public void pr( C_1_2_1 c )
    {
    System.out.println( "C_1_2_1" );
    }

    public static void main( String args[] )
    {
    InheritanceTest t = new InheritanceTest();
    t.pr( null );
    }
    }
      

  17.   

    alou()在重载方法中参数有可能混淆的情况下,编译器使用下面的策略:
    1. 如果发生混淆的位置上的所有参数类型在继承关系上构成一棵有分支的树,报错。
    2. 如果这些参数类型在继承关系上是一个队列,匹配类体系中最低级的那个。讲得很好啊,是你自己总结的还是哪本书上看来的?
      

  18.   

    这算不算动态绑定Late Binding啊?
      

  19.   

    有理有理!嘻嘻[这算不算动态绑定Late Binding啊?] overloading应该是前期编译时绑定,不是后期
    运行时绑定(override是)
      

  20.   

    to 忧郁的眼神,稀嘘的胡子喳:难怪是“忧郁的眼神,稀嘘的胡子喳”哦,总是昼伏夜出 ,xixi