关于这道题,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." 英文不好,哪位给精确翻译一下?
解决方案 »
- 文件中读数据
- 迷惘。。。散分。。。
- JDBC连接SQL Server 2000出错,但连接MySQL就没出错?
- 请问如何将一个ImageIcon对象转换为File对象或者利用Blob插入数据库中?
- javabean java类
- 本人有一批java及Delphi二手图书出售,大部分都是新书,本人在深圳,你可以根据自己的意愿开价,详情请看
- 求教:如何取得日期并将其安要求转换为字符串!
- CR校验
- 我有段出错的JAVA程序,但是不知道出错提示是什么意思,该怎么解决,请高手指导一下
- 一道java程序设计题
- 有人说Jcreate可以实现"."功能,但我的好象不行,是否需要什么设置?
- 如何判断一个字符串是否能够转换成为整数,如将"1"转换成1,注意,我问的是如何判断。谢谢!!
{
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解释成为什么类型。
希望高手指点。
高手来看看啊
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");
}
}
1.第一次看到null也可以做为参数传递,那么c.test(null)到底指向哪个对应的test()方法啊?
2.那行被注释掉的语句看到了吗?如果把注释去掉,那么整个程序编译就无法通过:错误信息很简单,就一句:一个错误在c.test(null);
3. 这道题用到了哪些知识点啊?
解释清楚了吗?
A<-B<-C
null将与C匹配。
因为有:Object<-Tester<-SubTester,所以没有String时null将与SubTester匹配。
而加上String后编译器无法决定调用那个函数所以出错。
test(SubTester),的参数无法用来调用test(String)或相反
所以test(null)不知道调用那个方法,不过如果程序中没有test(null)将不会出错
指向所能适应的最窄的(比如 参数是1,方法有参数类型int,float,它就会调int的),所以在本例中,它是指向public void test(SubTester s)
2、因为null可是任意对象类型的,所以JVM可以认为它是SubTester类型的,也可以是String类型的,主要到这两者不同于Tester和SubTester(他们是相容的),这时就产生了二义性错误!(不是什么 错误信息很简单,就一句:一个错误在c.test(null);试那里有二义性错误)
3、Java的方法重载。
你们说:根据面向对象的基本原理,应该找一个与他最匹配的参数,即:A<-B<-C,null将与C匹配。我不太明白,为什么null要与类体系的最低级匹配啊(我这样理解对吗?)。而且,加了void test(String s)后,为什么就无法确定调用哪个函数了呢?
test(SubTester)的参数无法用来调用test(String)或相反所以参数间的详细程度无法比较
所以test(null)不知道调用那个方法,不过如果程序中没有test(null)将不会出错
我总结一下,你们看对不对:
c.test(null)会和所有重载的void test()方法中参数类型最最详细的那个,也就是类体系中最低级的那个匹配。OK,我这还有个疑问:为什么JVM会搞不清void test(Sting s)和void test(SubTester s)到底哪个更加详细或低级呢?怎么对这种情况进行比较?
英文不佳,只可意会
一个不太正规的观点是如果一个方法的声明所调用的(参数)可以传递给另一个方法而不会产生编译期错误,则(使用)第一个方法(比另一个)更准确。
注:这也是第一行输出SubTester version的原因,因为null可以是任何类型传递给test(),但方法test(SubTester s)中的s可以传递给其它两个方法而不会出现编译期错误,当然反过来说则不行,所以认为test(SubTester s)更准确,输出的结果也证明了这一点。至于注释掉的那一句,前面的几位大虾已经解释得很清楚的了。
因为String和SubTester之间不存在任何的层次关系
你能判断出到底哪个更加详细或低级吗?
OK,做最后的“结案陈词”: c.test(null)会和所有重载的void test()方法中参数类型最最详细的那个,也就是类体系中最低级的那个匹配。各位高手看一下,如果我的认识没有问题的话就给分了。
在重载方法中参数有可能混淆的情况下,编译器使用下面的策略:
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 );
}
}
1. 如果发生混淆的位置上的所有参数类型在继承关系上构成一棵有分支的树,报错。
2. 如果这些参数类型在继承关系上是一个队列,匹配类体系中最低级的那个。讲得很好啊,是你自己总结的还是哪本书上看来的?
运行时绑定(override是)