java.lang.ClassCastException编译时检查可能已经处理得更好了

时间:2017-07-22 03:44:26

标签: java java-ee

我有两个类parent和child,clascastexception在运行时发生 对于下面给出的代码。

从下面的代码中可以明显看出有classcastexception。 我认为java可以在betterway中处理,因此在下面的情况下它可能会给出编译时错误。

我还有其他原因,java在编译期间没有给出错误。 只是想知道我是否缺少任何东西。

public class ClassCastExcp {

    public static void main(String args[]){
        Child chd = (Child) new Parent(); //it will force you to cast and gives classcastexception in runtime
    }

}

class Parent{
}

class Child extends Parent{
}

4 个答案:

答案 0 :(得分:3)

根据您所写的内容,我认为您完全理解为什么会遇到运行时异常。 (如果没有,请参阅其他答案。)

  

是否有任何原因导致java在编译期间没有出错。只是想知道我是否遗漏了什么。

它没有给出编译错误,因为根据JLS代码是合法的Java。 (有关更多详细信息,请参阅@ ajb的答案,但真正的解释是在JLS本身。)要求兼容的Java编译器接受此...至少在“兼容”模式下。

现在,允许Java编译器 报告类似这样的警告,并且还允许将警告升级为错误。但是:

  • 这个特殊的例子在实际代码中不太可能。编译器编写者通常不会为很少发生的错误实施警告。

  • 任何实施Java编译器的人都会在默认情况下将错误视为 ,这会给那些必须处理其他人/组织编写的代码的用户带来很多抨击。

答案 1 :(得分:2)

JLS 15.3中的这句话很重要:

  

换句话说,类型为T的表达式的值始终为   适合分配给T类型的变量。

这意味着如果表达式具有类类型T,那么在运行时,实际值可以是可以分配给类型T的变量的任何类型,即{{1}或任何子类。

语言规则是基于此编写的。因此,如果你说

T

表达式的类型为(T2)expression ,上面的句子意味着编译器只能假设在运行时表达式可以有类型T或某个子类。如果表达式可以转换为T,则演员表是合法的。在您的情况下,由于T2的某些子类可以转换为Parent,因此它是合法的。

Child的情况可能是特例;现在我们知道表达式必须具有类型new Parent()不能属于子类类型。但是对于Java来说这是违法的,规则必须重写(语言规范取决于精确规定的规则,因此程序可以在编译器之间移植;编译器实际上不允许使用"常识& #34)。 JLS必须使用"精确类型"或类似的东西来发明表达式的概念,然后需要更改许多其他规则来处理这种表达式。在几个地方添加这种规则需要做很多工作,并验证语言规则中的所有内容是否仍然一致;所有这些工作只会影响病态案例,例如您在实践中从未发生的原始帖子。因此,将Java作为非法行为绝对不值得。

答案 2 :(得分:0)

为简单起见,请参阅下面的代码段

 Object x = new Integer(0);
 System.out.println((String)x);

现在,println()方法需要String,因此我们将x类型的强制转换Object输入到String。但是,在运行时Object x获取Integer的实例。由于Integer无法投放到String。它会在运行时抛出ClassCastException异常。

现在,回到你的问题,这是一个向下铸造的例子。您不能将父实例存储到子级。请在您的帖子中参考@Axel评论的链接。

答案 3 :(得分:-1)

如果首先完成对象的向上投射然后向下投射,它将不会抛出classcastexception

Parent p1=new Child();    
Child chd = (Child) p1; // it will not throw classcastexception