【问题标题】:Object vs String Method [duplicate]对象与字符串方法[重复]
【发布时间】:2012-10-19 10:46:51
【问题描述】:

可能重复:
Overloaded method selection based on the parameter’s real type
How is an overloaded method choosen when a parameter is the literal null value?

当我执行下面的代码时,我得到以下输出:

调用字符串参数的方法..."

为什么?

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test(null);
    }
}

【问题讨论】:

  • 所以你有一个重载的方法'test'并且你用一个字符串调用它,但是你想知道为什么对象没有被调用?
  • 这只是因为String 类是Object 类的一种特殊形式(因为String 类除了具有Object 类的所有特性之外own) 由 JLS 指定的编译器选择(选择最具体的方法,在您的情况下,接受String 类型的参数的方法)。
  • 理论上空引用不是任何类型,那么为什么JVM选择String而不是Object。我认为因为 Object 是 Java 中每个类的基础,所以它应该调用带有 Object 参数的方法。
  • @Alpesh Gediya - 这是因为在您的情况下,null 可以同时解析为 StringObject。不是吗? (ObjectString 都可以是 null)因此,编译器会按照 Java 语言规范 (JSL) 中的规定选择最具体的方法,在您的情况下,最具体的方法是接受String 参数。

标签: java


【解决方案1】:

调用中的null 匹配两个test() 签名。您必须强制转换 null 以确保它调用其中一个。

【讨论】:

  • Java 还将尝试使用可用方法的最具体版本。这就是它选择 String 而不是 Object 的原因。
  • 我习惯了 Eclipse 告诉我在我有机会编写这种代码之前修复它。
【解决方案2】:

如果我没记错的话,一个类似的例子来自 Java Puzzles

null 可以是String 类型或Object 类型。但是 JVM 总是会选择更准确的方法。

在这种情况下,StringObject准确。 (StringObject,但 Object 可能不是 String)。

这样写代码不是一个好习惯。尝试强制转换参数以匹配您想要的方法,例如

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test((Object)null);
    }
}

【讨论】:

    【解决方案3】:

    我试过了:

    Test2.class

    public class Test2{}
    

    Test3.class

    public class Test3 extends Test2{
    
    }
    

    Test.class

    public class Test{
    
    public static void print(Object obj){
        System.out.println("Object");
    }
    
    public static void print(Test2 obj){
        System.out.println("test 2");
    }
    
    public static void print(Test3 obj){
        System.out.println("Test 3");
    }
    
    
    public static void main(String[]args){
        Test.print(null);
    }
    
    }
    

    它打印出 Test 3

    就像在您的场景中一样,这意味着如果一个方法被重载(并且当传递 null 时),它会识别具有 child-most 参数的方法。

    Object->Test->Test2
    

    或者在你的情况下:

    Object->String
    

    【讨论】:

      【解决方案4】:

      Java 试图找到可能调用的最具体的方法。 String 是 object 的子类,因此 Java 将尽可能地遵循 String 方法。对于 Object 或 String,null 是完全可以接受的值,但由于 String 比 Object 更具体,Java 遵循 String 方法,因为它更精确。

      【讨论】:

        【解决方案5】:

        null 可以是String 和/或Object,但因为String 继承自Object,它会尝试使用更精确的签名。你可以投null来选择执行哪个方法:

        public static void main(String[] args) {
            Test.test((Object) null); // treats as Object
            Test.test((String) null); // treats as String
            Test.test(null);          // treats as String
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-06
          • 1970-01-01
          • 2017-12-15
          • 2013-04-13
          • 2019-07-14
          • 2016-11-17
          • 1970-01-01
          相关资源
          最近更新 更多