为什么我不能如图所示分配对象?

时间:2014-05-10 00:22:28

标签: java object equals

我是java的新手。我正在读一本关于可比较和比较器接口的书中的章节。使用下面的代码,它会显示"找到一种方法来修改最后一行代码以使其工作" 。目前,它没有编译。最后一行该怎么办?

Hello Friend= new Hello("LOL");
Object myObj = Friend;
Hello myFriend = myObj; // What's wrong with this line ?

4 个答案:

答案 0 :(得分:3)

Hello Friend= new Hello("LOL");

现在你有一个名为Friend的编译时类型Hello的变量引用运行时类型为Hello的对象

Object myObj = Friend;

现在您有一个名为myObj的编译时类型Object 的变量,它指的是运行时类型Hello的同一对象。这是允许的,因为每个Hello也是Object

Hello myFriend = myObj; // What's wrong with this line ?

这在编译期间失败,因为myObj具有编译时类型Object,并且您正在尝试将其分配给编译时类型Hello的新变量。大多数Object都不是Hello。编译器并没有试图弄清楚这个特定的是否是,因为这通常是不可能的。

但是你可以强制编译器无论如何都要确保这个特定Object实际上是Hello

Hello myFriend = (Hello) myObj;

这称为casting

答案 1 :(得分:1)

从评论中复制:

  

您之前放置myObj = 5;的图像,您可以将其定义为对象。 Hello myFriend = 5意味着什么?

您遇到的问题(“不兼容的类型”)是因为您尝试将定义为Object的变量(在层次结构的顶部)分配给 变量定义为Hello(层次结构中的底部)。在你的情况下它可能会起作用,但是编译器禁止这样做,因为它没有(可行的)方式知道在之间或之后发生了什么。

这也是一个有效的陈述:

Object myObj = Friend;
myObj = 5;

但是将5分配给Hello类型的变量显然不起作用。这就是为什么它完全禁止这一切。

您可以通过显式转换(Hello myFriend = (Hello) myObj;)来规避这一点,但如果它是一个不可能的转换,这将抛出运行时异常。

答案 2 :(得分:0)

我认为你的意思是分配,而不是等同。该行失败,因为运算符是由编译时类型选择的。您无法将Object分配给Hello,因为您可以将GoodBye类的实例绑定到Hello类型的引用。

这可以用于非静态类型的其他语言(因为运行时的类型是兼容的),但不是Java。

答案 3 :(得分:0)

您已“删除”Friend的类型,

// The root of the Java class hierarchy is Object, that mean that 
Object myObj = Friend; // <-- (Object) can refer to anything! String, Double, Hello. :)
                       // Or, every instance of anything is-a java.lang.Object.
Hello myFriend = (Hello) myObj; // minimum

你应该做的是instanceof

Object myObj = Friend;
if (myObj instanceof Hello) { // <-- runtime type checking. 
  myFriend = (Hello) myObj;
}

Class#isAssignableFrom(Class) -

Object myObj = Friend;
if (Hello.class.isAssignableFrom(myObj)) { // <-- runtime type checking. 
  myFriend = Hello.class.cast(myObj); // <-- you can also cast with this.
}