2015-11-30 50 views
-2
public class Test{ 

public static void m1(Object o){ 
    System.out.println("object called"); 
} 

public static void m1(String s){ 
    System.out.println("String called"); 
    } 
} 

现在,这里是下面的情况下,爪哇:使参数相同的方法签名以外的参数类型

  • M1( “串”); 输出:字符串
  • m1(new String(“string”)); 输出:字符串调用
  • Object o =“string”; m1(o); 输出:名为
  • 的对象
  • Object o = new String(“string”); m1(o); 输出:名为
  • 的对象
  • Object o = new Object(); m1(o); 输出:对象叫做

有人能解释一下上面的场景吗?

+1

你的每个变量'o'被定义为'Object',因此它调用'm1(Object)'。用'String'调用同样的情况。 – SomeJavaGuy

+0

'Object o =“string”'执行类型擦除,你迫使'String'被认为是一个通用的'Object'。将'o'传递给'm1()'使用对象版本,因为这是变量'o'的类型。 –

回答

2

的决定是在编译时间作出的,基于在正在传递的表达式的类型。因此,

  • m1("string")使用String版本(因为文字是String类型)

  • m1(new String("string"))使用String版本,因为表达式new String("string")是类型的String

  • 所有第您m1(o)者的稀土元素使用Object版本,因为o类型为Object(根据声明)

再次为重点,具体类型是什么o指不要紧,它是静态类型的编译器使用的表达式来确定调用哪个超载。

这意味着如果你改变了表达的类型,你可以让编译器做出了不同的选择:

Object o = "string"; 
m1((String)o); // Calls the String version 

有专门为方法调用表达式JLS的整个片:§15.12: Method Invocation Expressions。相关小节是§15.12.2: Compile-Time Step 2: Determine Method Signature

+0

T.J.克罗德谢谢! – BaajiRao

相关问题