繁体   English   中英

执行Casting时发生执行阶段例外

[英]Runtime exception when doing a Casting

进行Casting时出现运行时异常,如下所示

线程“主”中的异常java.lang.ClassCastException:无法在Testing.main(Testing.java:5)上将A强制转换为B

public class A {

    public void printA()
    {
        System.out.println("A");
    }

}




public class B extends A{

    public void printB()
    {
        System.out.println("B");
    }
}

public class Testing {

    public static void main(String args[]) {

        B b = (B) new A();
        b.printA();
    }

}

但是为什么这段代码可以正常运行

因为我们在这里做同样的事情

HttpServletRequest request = (HttpServletRequest) req;

public class LogFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String ipAddress = request.getRemoteAddr();
        chain.doFilter(req, res);
    }

由于req具有HttpServletRequest实际类型,因此可以向下转换。

您可以使用System.out.println(req.getClass());

但是,在你的情况你的实际对象类型的A ,因为new A()所以你不能将其转换B

可行的方案:

A a = new B(); //actual type is B
B b = (B)a;

第二条陈述B b = (B)a; 被允许,因为它被创建时的对象的实际类型是B由于new B()只是引用类型是A 因此,您可以再次将其转换回B

您不是在做同一件事。

在第二个示例中,req是HttpServletRequest的实例。

在第一个示例中,A不是B的实例。

A不是B的实例,因此您不能在这种情况下灰心。

考虑一下,A是动物,B是布法罗。

现在,布法罗扩展了Animal。

然后,在您的代码中执行以下操作:

Buffalo b =(Buffalo)new Animal();

这是错误的,因为动物没有扩大水牛城!

您应该仅将对象强制转换为一个类。

因此,如果您有扩展“动物”的水牛城,则可以将其投射为“动物”(因为它是其中一个)。

但是您不能将动物投掷到水牛城,因为并非所有动物都是水牛城。

您是在告诉编译器(通过显式强制转换)信任您您没有犯错误,因此它忽略了错误并且在编译时未检测到错误。 这就是为什么您不会遇到编译错误的原因 但是,当程序运行时,您会得到一个异常,因为A 不是 B的实例。 您可能想做:

A b = (A) new B();

请注意,如果删除显式强制转换,则会出现编译错误 (总是首选),因为编译器已经知道您在做错误。

在另一个示例中,您认为它是相同的..嗯..这是不相同的,那里, reqHttpServletRequest一个实例。

当你做一个new A ,你不能将它转换为B ,因为B是的子类A (又该否则属性和mothods定义B ,但不是A样子?)

HttpServletRequest request = (HttpServletRequest) req; req是在其他地方创建的,它是一个HttpServletRequest

原因HttpServletRequestServletRequest 在您的示例中, A不一定是B ,可以是AC或任何子类。

让我们来看看动物的例子,它更容易。

class Animal{}
class Dog extend Animal{}
class Cat extend Animal{}

在主要。

       Animal a= new Animal();
       Dog dog = (Dog)a;// A dog is an animal but not all animals are  dog

动物不可能是狗,也可能是猫,或者像本例中的Animal这样的其他东西,然后ClassCastException 为了避免此runtimeException,可以使用instanceof运算符。

这不会引发异常,因为servletrequest是HttpServletRequest的超级接口。

这类似于动态多态性。 如果您编写了一个接口B,然后将A对象转换为B,那么它将起作用。

http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM