2016-01-27 20 views
5

为什么A的实例可以转换为List但不能转换为String?Java海关类实例不能强制转换为String。为什么?

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

因为...这不是一个字符串。 –

+1

添加到Andy的答案List是一个接口,而String是类。如果你调用列表中的方法,那么它会抛出错误 –

+0

但它不是一个列表... –

回答

6

根据规范,编译器在对转换进行这些检查时仅考虑声明类型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总是失败。

当然,在演习中,演员阵容在实践中会失败。但不是在编译时。

7

引用JLS

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

StringA是不相关的类,所以它是一个编译时错误。 List是一个接口,所以不会导致相同的错误。

请注意,您的说法

A的实例可以施展列出

是不太正确的:A无法被转换为List;这只是一个运行时间故障,而不是编译时间故障。

+0

嘿@ShadowDroid - 我拒绝了你的编辑,因为我不想为你的见解记下功劳。随意发表评论,或者作为答案提交,我会很高兴地为它提供支持。 –

+0

我没有帮助获得信用/投票。我只是想分享知识。反正@Erwin贴出了一个很好的详细样本答案。 –

1

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

对您而言,A类不是String的子类。因此A不能转换为String。另外,String是最后一个阶级,因此您无法编写可投射到String的类A

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

要记住,toString()方法的存在并不意味着A是一个字符串是很重要的,而这意味着你可以从A一个字符串,有些描述A实例。如果您发现缺少为您的目的所提供的描述,您可以覆盖AtoString()方法的作为替代是用Java编写返回一个更好的描述,像这样

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

,您还可以包括任何变量或其他项目,你最终可以变成一个字符串(因为所有的对象都有toString()几乎包括任何东西)。

相关问题