Java 对象与字符串方法

Java 对象与字符串方法,java,Java,可能重复: 当我执行下面的代码时,我得到以下输出: 名为“”的字符串参数的方法 为什么? 调用中的null匹配两个test()签名。您必须强制转换null,以确保它调用其中一个签名。如果我回忆正确,类似的示例来自Java拼图 null可以是String类型或Object类型。但是JVM总是会选择一种更精确的方法 在这种情况下,字符串比对象更准确(字符串是对象,但对象可能不是字符串) 这样编写代码不是一个好习惯。请尝试强制转换参数以匹配所需的方法,如 public class StringOb

可能重复:

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

名为“”的字符串参数的方法

为什么?


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

如果我回忆正确,类似的示例来自Java拼图

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

在这种情况下,
字符串
对象
更准确(
字符串
对象
,但
对象
可能不是
字符串

这样编写代码不是一个好习惯。请尝试强制转换参数以匹配所需的方法,如

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);
    }
}

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

 null
可以是
字符串
和/或
对象
,但由于
字符串
继承自
对象
,它将尝试使用更精确的签名。您可以强制转换
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
}
我试过这个:

Test2.class

public class Test2{}
public class Test3 extends Test2{

}
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);
}

}
Test3.class

public class Test2{}
public class Test3 extends Test2{

}
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);
}

}
测试类

public class Test2{}
public class Test3 extends Test2{

}
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);
}

}
它打印出测试3

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

Object->Test->Test2
或者在您的情况下:

Object->String

因此,您有一个重载方法“test”,并使用字符串调用它,但您想知道为什么没有调用对象一?这只是因为
string
类是
对象
类的一种特殊形式(由于
String
类除了拥有自己的
对象
类的所有特性外,还拥有
对象
类的所有特性),编译器根据JLS的规定选择了该类(在您的情况下,选择了最具体的方法,即接受
String
类型参数的方法)。这些也是您可能想要引用的类似线程,理论上空引用不是任何类型,那么为什么JVM选择字符串而不是对象。我认为,由于对象是Java中每个类的基础,因此它应该使用对象参数调用方法。@Alpesh Gediya-这是因为在您的情况下,
null
可以解析为
字符串
以及to
对象
。不是吗?(对象和字符串都可以是
null
),因此,编译器根据Java语言规范(JSL)中的规定选择最具体的方法在您的例子中,最具体的方法是接受
字符串
参数的方法。Java还将尝试使用可用方法的最具体版本。这就是为什么它选择字符串而不是对象。我习惯于Eclipse告诉我在我有机会编写此类代码之前修复它。