我是java的新手。我正在读一本关于可比较和比较器接口的书中的章节。使用下面的代码,它会显示"找到一种方法来修改最后一行代码以使其工作" 。目前,它没有编译。最后一行该怎么办?
Hello Friend= new Hello("LOL");
Object myObj = Friend;
Hello myFriend = myObj; // What's wrong with this line ?
答案 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.
}