为什么A的实例可以转换为List但不能转换为String?Java海关类实例不能强制转换为String。为什么?
class A{}
...
A a = new A();
List list = (List)a; //pass
String s = (String)a; //compile error
为什么A的实例可以转换为List但不能转换为String?Java海关类实例不能强制转换为String。为什么?
class A{}
...
A a = new A();
List list = (List)a; //pass
String s = (String)a; //compile error
根据规范,编译器在对转换进行这些检查时仅考虑声明类型a
。
所以,你写的:
A a = new A();
但是,编译器只考虑
A a; // = <something>;
所以它知道a
不能为String
,因为一个类只能有一个父类(多重继承),不能有类A
的子类也是一个字符串。
但是,对于接口,这是不正确的。因此,尽管我们知道,类A
没有实现List
,有可能是这样定义的类B
:
class B extends A implements List {}
而且因为编译器只考虑声明的类型,它必须假定它也可以在你分配new B()
至a
。
因此,因为A
的子类可以实现接口List
,所以编译器无法假定转换为List
总是失败。
当然,在演习中,演员阵容在实践中会失败。但不是在编译时。
引用JLS:
它是一个编译时间错误,如果,对于任何两个类(不接口)Vi和Vj的Vi是不VJ的一个子类,或反之亦然。
String
和A
是不相关的类,所以它是一个编译时错误。 List
是一个接口,所以不会导致相同的错误。
请注意,您的说法
A的实例可以施展列出
是不太正确的:A
无法被转换为List
;这只是一个运行时间故障,而不是编译时间故障。
嘿@ShadowDroid - 我拒绝了你的编辑,因为我不想为你的见解记下功劳。随意发表评论,或者作为答案提交,我会很高兴地为它提供支持。 –
我没有帮助获得信用/投票。我只是想分享知识。反正@Erwin贴出了一个很好的详细样本答案。 –
Java中的类只能转换为其超类型之一,或者其超类型之一的接口之一。
对您而言,A
类不是String
的子类。因此A
不能转换为String
。另外,String
是最后一个阶级,因此您无法编写可投射到String
的类A
。
Java已经认识到需要轻松地将类显示为字符串,特别是为了调试/日志记录的目的。为了满足这种需求,Object
类带有toString()
方法。由于所有Java类都从Object
类扩展而来,所有Java类都包含toString()
方法的实现。
要记住,toString()
方法的存在并不意味着A
是一个字符串是很重要的,而这意味着你可以从A
一个字符串,有些描述A
实例。如果您发现缺少为您的目的所提供的描述,您可以覆盖A
的toString()
方法的作为替代是用Java编写返回一个更好的描述,像这样
@Override
public String toString() {
return "my better description";
}
,您还可以包括任何变量或其他项目,你最终可以变成一个字符串(因为所有的对象都有toString()
几乎包括任何东西)。
因为...这不是一个字符串。 –
添加到Andy的答案List是一个接口,而String是类。如果你调用列表中的方法,那么它会抛出错误 –
但它不是一个列表... –