我对以下两个程序的输出感到困惑。
当我在程序1中只有两个参数为String
和Object
的方法时,它会将输出设为String
。
但是当我在程序2中添加一个参数为Integer
的新方法时,它不会编译并给出错误
对于类型testNull
计划1:
package onkartest;
public class TestNull {
public static void nullTest(Object b)
{
System.out.println("object");
}
public static void nullTest(String x)
{
System.out.println("String");
}
public static void main(String x[])
{
nullTest(null);
}
}
输出:字符串
计划2:
package onkartest;
public class TestNull {
public static void nullTest(Object b)
{
System.out.println("object");
}
public static void nullTest(String x)
{
System.out.println("String");
}
public static void nullTest(Integer i)
{
System.out.println("Integer ");
}
public static void main(String x[])
{
nullTest(null);
}
}
输出:
线程中的异常" main" java.lang.Error:未解决的编译问题:
对于类型testNull
,nullTest(Object)方法不明确在onkartest.testNull.main(testNull.java:26)
如果我只使用Object
参数方法运行程序,它会将输出设为Object
。
你能解释一下这种行为背后的原因吗?
答案 0 :(得分:2)
在确定使用哪个函数时,Java将尝试使用最具体的输入参数查找函数。所以在第一种情况下,选择String函数为null可以赋给String。 Object是String的父级,因此String函数将更具体。
在第二种情况下,Integer和String都继承自Object,并且这两者都可以赋值为null。因此,它们都是同样具体的,Java无法决定使用这些函数中的哪一个。
答案 1 :(得分:2)
原因是在方法重载的情况下,当传递一个可以被子类和父类引用的参数时,将始终调用带有子类类型参数的方法。
String是Object的子类,因此调用其方法。
在以下示例中,我们将类Parent
视为Object
类和Child
类,可以将其视为String
类。
现在你的程序1发生了什么,完全相同的事情发生了,那就是带有子类对象参数的方法被调用
public class Program
{
public static void method(Parent p1)//Consider the Parent as Object
{
System.out.println("parent");
}
public static void method(Child c)//Consider the Child as String
{
System.out.println("Child");
}
public static void main(String []args)
{
method(null);
}
}
class Parent//consider Parent as Object
{
}
class Child extends Parent//consider Child as String
{
}
但是现在假设您添加了以下可以被视为Child2
类的类Integer
。 Child2
是Parent
的子类,就像Integer
是Object
class Child2 extends Parent
{
}
并添加以下方法
public static void method(Child2 c)//Consider the Child2 as Integer
{
System.out.println("Child");
}
现在发生的事情正是程序中发生的事情2.原因是编译器无法确定哪一个是正确的,因为它们都是同一个父类的子类,而且最重要的是,没有一个(Child2或Child)是另一个的父母。
如果我们有一个案例,我们将2个类中的任何一个作为另一个类的子类并且都继承了父类,那么就没有歧义,并且将调用带有子类的方法。
答案 2 :(得分:1)
当尝试将参数传递给方法时,首先尝试完全相同的类型。如果没有,那么尝试立即超级类型。在第一个程序中,Object超出字符串,因此它与String匹配。但是在第二个程序中,Object类有两个相同级别的子级,因此java编译器无法找到哪个要映射的空值。