将字符串转换为对象,但不是将对象转换为字符串?

6
我不太理解为什么这行代码无法编译:

我不太理解为什么这行代码无法编译:

String str = new Object();

而以下内容则可以:

Object o = new String("Hello");

据我理解,String类和其他所有类一样,都是继承自Object类。那么为什么第一行代码不能编译呢?

右侧的对象类型必须是左侧类型或其扩展。该对象既不是字符串也不扩展字符串。 - takendarkk
19
你需要找到一篇关于面向对象编程的基础教材并学习它。(认真对待。你不可能从 Stack Overflow 上的 100 字回答中理解这些概念。) - Hot Licks
2个回答

23

因为String是一个Object,但Object并不是一个String,就像每个桔子都是一种水果,但不是每种水果都是桔子

String是一个扩展了Object的类,因此你可以简单地写:

Object obj = "string";

但是Object没有继承String,因此:

String str = new Object();

编译失败。

但是,如果您有一个Object,并且它是一个String,则可以执行一些称为类型转换或简单地称为转换的操作:

String str = (String) myObject;

但是如果myObject最初不是String类型,它可能会抛出ClassCastException异常。

在这里,您可以找到有关Java中对象转换的更多信息:http://www.javabeginner.com/learn-java/java-object-typecasting


那么语句String str = new Object();的大致翻译是:str是String类型的一个对象?我试图直观理解如何阅读该行代码。 - wonggr
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Victor2748

4
对于这种情况,区分变量的类型(在其声明中确定)和对象的类别(在创建对象时确定)是有用的。
变量可以为null,或指向与其类型匹配的任何对象,或该类的直接或间接子类。因为StringObject的子类,所以类型为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。但是在String test2 = (String) integerObject;这一行上会出现ClassCastException异常。就编译器而言,integerObject可能指向一个String,所以它接受了我的强制转换。在运行时,JVM发现它实际上指向一个Integer,并抛出了异常。
使用类型Object来声明integerObject是有意义的。这使得String test2 = (String) integerObject;将类型为Object的表达式转换为类型为String的转换成为可能,这取决于integerObject实际引用的内容。如果integerObject声明为Integer类型,则编译器将拒绝该程序。没有对象可以被IntegerString表达式同时引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接