Java Customs类实例无法强制转换为String。为什么?

时间:2016-01-27 12:48:18

标签: java

为什么A的实例可以转换为List而不能转换为String?

class A{}
...
A a = new A();
List list = (List)a;   //pass
String s = (String)a;  //compile error 

3 个答案:

答案 0 :(得分:7)

引用JLS

  

如果对于任何两个类(非接口)Vi和Vj,Vi不是Vj的子类,反之亦然,那么这是一个编译时错误。

AList是不相关的类,因此它是编译时错误。 A是一个接口,因此不会导致相同的错误。

请注意你的断言

  

A的实例可以转换为List

不完全正确:List 无法投放到.;它只是运行时故障,而不是编译时故障。

答案 1 :(得分:6)

根据规范,编译器在对转换进行这些检查时仅考虑声明的a类型。

所以,你写道:

A a = new A();

但编译器只考虑

A a; // = <something>;

所以它知道a不能是String,因为一个类只能有一个超类(没有多重继承),所以不能成为类{{1}的子类这也是一个字符串。

但对于接口来说,这不是真的。因此,虽然我们知道课程A没有实现A,但可能会有一个类List定义如下:

B

由于编译器只考虑声明的类型,因此必须假设您已将class B extends A implements List {} 分配给new B()

因此,因为a的子类可以实现接口A,所以编译器不能假设转换为List总是失败。

当然,演员会在练习中失败 - 在运行时。但不是在编译时。

答案 2 :(得分:1)

Java中的类只能转换为其超类型之一,或其超类型之一的接口之一。

在您的情况下,类String不是A的子类。因此String无法投放到String。此外,A是一个最终类,因此您无法编写可以转换为String的类Object

Java已经认识到需要轻松地将类显示为字符串,尤其是出于调试/日志记录的目的。为满足此需求,toString()类附带Object方法。由于所有Java类都从toString()类扩展,因此所有Java类都包含toString()方法的实现。

重要的是要记住,A方法的存在并不意味着A是一个字符串,而是意味着你可以从A得到一个字符串描述A实例。如果您发现所提供的说明不适合您的目的,您可以覆盖toString()的{​​{1}}方法并返回更好的说明,就像这样

@Override
public String toString() {
  return "my better description";
}

由于覆盖是用Java编写的,您还可以包含任何变量或其他项目,最终可以将其转换为字符串(因为所有对象都包含toString()几乎所有内容)。