执行强制转换时的运行时异常

时间:2014-01-08 13:44:52

标签: java

我在执行Casting时遇到运行时异常,如下所示

线程“main”中的异常java.lang.ClassCastException:A不能转换为B     在Testing.main(Testing.java:5)

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);
    }

7 个答案:

答案 0 :(得分:7)

由于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

答案 1 :(得分:5)

你没有做同样的事情。

在你的第二个例子中,req是HttpServletRequest的一个实例。

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

答案 2 :(得分:2)

A不是B的实例,因此您无法在您的方案中进行转发。

考虑一下,A是Animal,B是Buffalo。

现在,Buffalo扩展了Animal。

然后,在您的代码中,您执行:

布法罗b =(布法罗)新动物();

这是错误的,因为动物没有扩展布法罗!

您应该只转换为该对象确实存在的类。

因此,如果您有一个扩展Animal的Buffalo,您可以将它投射到Animal(因为它是一个)。

但你不能将动物施放到布法罗,因为并非所有的动物都是水牛。

答案 3 :(得分:1)

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

A b = (A) new B();

请注意,如果删除显式强制转换,则会出现编译错误(这总是更可取),因为编译器已经知道您犯了错误。

在另一个例子中,你认为它是相同的......嗯......它不一样,reqHttpServletRequest的一个实例。

答案 4 :(得分:1)

当您执行new A时,您无法将其强制转换为B,因为BA的子类(否则属性和方法中定义的属性) B但不是A看起来像?)

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

答案 5 :(得分:0)

原因HttpServletRequestServletRequest。 在您的示例A中,B不是A,可以是Cclass 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

主要。

ClassCastException

动物不能是一只狗可以是猫或其他类似于动物的东西,然后抛出instanceof。要避免此runtimeException,可以使用{{1}}运算符。

答案 6 :(得分:0)

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

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

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