Java 方法重载并选择最特定的类型

Java 方法重载并选择最特定的类型,java,static-methods,overloading,Java,Static Methods,Overloading,示例代码是: public class OverloadingTest { public static void test(Object obj){ System.out.println("Object called"); } public static void test(String obj){ System.out.println("String called"); }

示例代码是:

    public class OverloadingTest {

       public static void test(Object obj){
           System.out.println("Object called");
       }

       public static void test(String obj){
           System.out.println("String called");
       }

       public static void main(String[] args){
           test(null);
           System.out.println("10%2==0 is "+(10%2==0));
           test((10%2==0)?null:new Object());
           test((10%2==0)?null:null);
   }
输出为:

调用的字符串
10%2==0为真
被调用的对象
调用的字符串

test(null)
的第一次调用调用带有
String
参数的方法,根据
Java语言规范
这是可以理解的

1) 有人能解释一下在前面的调用中调用
test()
的依据是什么吗

2) 同样,当我们放置时,说一个
if
条件:

    if(10%2==0){
        test(null);
    }
    else
    {
        test(new Object());
    }
它总是使用
String
参数调用方法


编译器会在编译时计算表达式
(10%2)
?我想知道表达式是在编译时还是在运行时计算的。谢谢。

我认为你的问题在于你做出了错误的假设,你的表达方式:

test((10%2==0)?null:new Object());
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B


将始终调用test(null),这就是它们将通过test(Object)的原因

我认为你的问题在于你做出了错误的假设,你的表达方式:

test((10%2==0)?null:new Object());
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B

将始终调用test(null),这就是它们将通过test(Object)的原因

同:

Object o;

if(10%2==0)
    o=null;
else
    o=new Object();

test(o);
由于
o
的类型是
Object
(就像
(10%2==0)的类型一样),因此将始终调用null:newobject()
测试(Object)
o
的值无关紧要

同:

Object o;

if(10%2==0)
    o=null;
else
    o=new Object();

test(o);

由于
o
的类型是
Object
(就像
(10%2==0)的类型一样),因此将始终调用null:newobject()
测试(Object)
o
的值无关紧要。

您的答案是:运行时因为在运行时指定参数是否为字符串实例,所以在编译时无法找到它。

您的答案是:运行时因为在运行时指定参数是否为字符串实例,所以在编译时无法找到这。

正如@Banthar提到的结束
?:
操作符首先为变量赋值,然后评估条件。
另一方面,您提到的
if
条件总是返回true,因此编译器将只使用
if

的主体替换整个
if
块,因为@Banthar sinetend the
?:
操作符首先为变量赋值,然后计算条件。 另一方面,您提到的
if
条件总是返回true,因此编译器将仅用
if
1)if1)的
test()
方法由编译时的参数类型决定:

test((Object) null);
test((Object)"String");
输出:

Object called
Object called
2) 编译器更加智能,编译后的代码相当于:

test(null);
您可以使用
javap-c
检查字节码:

   0: aconst_null   
   1: invokestatic  #6                  // Method test:(Ljava/lang/String;)V
   4: return  
1)
test()
方法由编译时的参数类型决定:

test((Object) null);
test((Object)"String");
输出:

Object called
Object called
2) 编译器更加智能,编译后的代码相当于:

test(null);
您可以使用
javap-c
检查字节码:

   0: aconst_null   
   1: invokestatic  #6                  // Method test:(Ljava/lang/String;)V
   4: return  
这就是我们对这个问题的看法

如果有多个方法声明可访问且适用 对于方法调用,必须选择一个来提供 运行时方法分派的描述符。Java编程 语言使用的规则是选择最具体的方法

这是您案例中的测试(字符串)方法

正因为如此,如果你加上

public static void test(Integer obj){
           System.out.println("Ingeter called");
       }
它将显示编译错误-类型重载测试的方法测试(字符串)不明确

正如JLS所说:

可能没有最具体的方法,因为有 两个或多个最大特定方法。在这种情况下:

如果所有最大特定方法具有相同的签名,则: 如果其中一个最大特定的方法未声明为抽象,则 这是最具体的方法。否则,所有的 方法必须声明为抽象的。最具体的方法是 在最大特定的方法中任意选择。但是, 大多数特定的方法被认为是在以下情况下引发选中的异常: 仅当在每个 最大特定方法。否则,我们说该方法 调用不明确,会发生编译时错误

这就是我们对这个问题的看法

如果有多个方法声明可访问且适用 对于方法调用,必须选择一个来提供 运行时方法分派的描述符。Java编程 语言使用的规则是选择最具体的方法

这是您案例中的测试(字符串)方法

正因为如此,如果你加上

public static void test(Integer obj){
           System.out.println("Ingeter called");
       }
它将显示编译错误-类型重载测试的方法测试(字符串)不明确

正如JLS所说:

可能没有最具体的方法,因为有 两个或多个最大特定方法。在这种情况下:

如果所有最大特定方法具有相同的签名,则: 如果其中一个最大特定的方法未声明为抽象,则 这是最具体的方法。否则,所有的 方法必须声明为抽象的。最具体的方法是 在最大特定的方法中任意选择。但是, 大多数特定的方法被认为是在以下情况下引发选中的异常: 仅当在每个 最大特定方法。否则,我们说该方法 调用不明确,会发生编译时错误


Java使用早期绑定。最具体的方法是在编译时选择的。根据参数数量和参数类型选择最具体的方法。在这种情况下,参数的数量不相关。Th