2010-06-13 59 views
16

我有以下代码:
这段java代码的解释是什么?

public class Main { 
    public void method(Object o) 
    { 
      System.out.println("Object Version"); 
    } 
    public void method(String s) 
    { 
      System.out.println("String Version"); 
    } 
    public static void main(String args[]) 
    { 
      Main question = new Main(); 
      question.method(null);//1 
    } 
} 

为什么结果是“字符串版本”?以及为什么如果第一个方法需要StringBuffer对象时会出现编译器错误?
另一种情况:如果第一种方法需要StringBuffer对象,而我写入question.method("word");,则结果将为“字符串版本”。为什么?为什么没有编译器错误?

+0

好奇。我期望编译器在那里发牢骚,但也许两个参数类之间存在一种类型关系(“String”是更具体的)会改变事情,这是JLS中的情况吗? 'StringBuffer'的情况很简单,因为它确实含糊不清。 – 2010-06-13 19:42:03

+1

@第三个问题:当然你不会得到一个错误。你传递一个字符串,所以带有String参数的方法显然会被调用。编译器没有什么可以混淆的。 – someguy 2010-06-13 20:07:52

回答

23

JAVA规范说,在这种情况下,最具体的函数将被调用。由于String是Object的子类型 - 第二个方法将被调用。 如果将Object更改为StringBuffer - 由于StringBuffer不是String的子类型,因此没有具体的方法,反之亦然。在这种情况下,编译器不知道调用哪个方法 - 因此是错误。

1

当看另一种情况时:

package com.snamellit;

public class Main { 
    public void method(Object o) { 
     System.out.println("Object Version"); 
    } 

    public void method(String s) { 
     System.out.println("String Version"); 
    } 

    public static void main(String args[]) { 
     Main question = new Main(); 
     question.method("word"); 
    } 
} 

如果第一方法tqkes一个StringBuffer和第二字符串,没有混乱尽可能“字”是字符串,而不是一个StringBuffer。

在Java中,函数/方法的标识取决于3件事:名称,类型参数(又名参数签名)和类加载器。由于这两种类型都有不同的参数签名,因此编译器可以轻松选择正确的参数并且不会引发错误。

+0

但它_does_会产生一个错误:你能说一下吗,彼得? – 2010-06-13 20:09:50

+0

感谢Peter.I认为应该发生编译器错误,因为“word”是一个有效的StringBuffer值。 – 2010-06-13 20:15:32

+2

不,它是一个字符串,而不是一个StringBuffer。 StringBuffers是Strings的可变表亲,它是不可变的,因此也是字符串的一个很好的模型。智者说:“如果有疑问,试试看”:System.out.println(“word”.getClass()。getName())将打印java.lang.String。 – 2010-06-13 20:55:28