我无法理解为什么这行代码无法编译:
String str = new Object();
以下内容:
Object o = new String("Hello");
据我所知,String与其他所有类一样,扩展了Object。那么为什么第一行不能编译?
答案 0 :(得分:23)
因为String
是Object
,但Object
不是String
,就像每个橙色都是 fruit < / strong>,但不是每个水果都是橙色。
String
是一个扩展Object
的类,因此您只需编写:
Object obj = "string";
但Object
不会延伸String
,所以:
String str = new Object();
不会编译。
但是,如果您有一个Object
并且它是String
,那么您可以执行一些名为 type casting 或只是 cast :
String str = (String) myObject;
但如果ClassCastException
最初不属于myObject
String
在这里,您可以在Java中找到有关 Object Casting 的更多信息:http://www.javabeginner.com/learn-java/java-object-typecasting
答案 1 :(得分:4)
对于这种事情,区分在其声明中建立的变量的类型和在创建对象时建立的对象的类是有用的。
允许变量为null
,或指向类与其类型匹配的任何对象,或者是该类的直接或间接子类。由于String
是Object
的子类,因此Object
类型的变量可以指向类String
的对象。
在您的示例中,编译器知道String
表达式必须是null
或指向String
对象,因此在编译时已知Object o = new String("Hello");
是正确的
另一方面,类型Object
的表达式或变量可能引用String,但它可能引用完全不同的东西。编译器需要显式转换才能说转换正常。
public class Test {
public static void main(String[] args) {
Object stringObject = "xyzzy";
Object integerObject = new Integer(3);
String test1 = (String)stringObject;
System.out.println(test1);
String test2 = (String) integerObject;
System.out.println(test2);
}
}
这个程序编译是因为我告诉编译器我的演员阵容的转换是可以的。它会通过第一次println
调用,因为stringObject
确实指向String
。它在ClassCastException
行上String test2 = (String) integerObject;
失败。就编译器而言,integerObject
可能指向String
,因此它接受了我的演员。在运行时,JVM发现它确实指向Integer
并抛出异常。
对integerObject使用类型Object
非常重要。这使得String test2 = (String) integerObject;
类型对象表达式转换为String类型,转换可能会成功,具体取决于integerObject
实际引用的内容。如果integerObject
已声明类型为Integer
,则编译器将拒绝该程序。 Integer
和String
表达式都无法引用任何对象。