简体   繁体   English

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

[英]Runtime exception when doing a Casting

I am getting a Runtime exception when doing a Casting as shown below 进行Casting时出现运行时异常,如下所示

Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B at Testing.main(Testing.java:5) 线程“主”中的异常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();
    }

}

But why this code runs fine 但是为什么这段代码可以正常运行

as we are doing the same thing here 因为我们在这里做同样的事情

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

Because the req has actual type of HttpServletRequest , so it can be downcasted. 由于req具有HttpServletRequest实际类型,因此可以向下转换。

You can check that using System.out.println(req.getClass()); 您可以使用System.out.println(req.getClass());

But in your case your actual object is of type A because of new A() , so you cannot cast it to B 但是,在你的情况你的实际对象类型的A ,因为new A()所以你不能将其转换B

Scenario that is working: 可行的方案:

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

The second statement B b = (B)a; 第二条陈述B b = (B)a; is allowed because the actual type of the object when it was created was B because of new B() , just the reference type was A . 被允许,因为它被创建时的对象的实际类型是B由于new B()只是引用类型是A That's why you can again cast it back to B . 因此,您可以再次将其转换回B

You're not doing the same thing. 您不是在做同一件事。

In your second example req is an instance of HttpServletRequest. 在第二个示例中,req是HttpServletRequest的实例。

In your first example A is not an instance of B. 在第一个示例中,A不是B的实例。

A is not an instance of B, hence you can't downcast in your scenario. A不是B的实例,因此您不能在这种情况下灰心。

Consider this, A is Animal and B is Buffalo. 考虑一下,A是动物,B是布法罗。

Now, Buffalo extends Animal. 现在,布法罗扩展了Animal。

Then, in your code, you do: 然后,在您的代码中执行以下操作:

Buffalo b = (Buffalo) new Animal(); Buffalo b =(Buffalo)new Animal();

This is wrong as the Animal isn't extending the Buffalo! 这是错误的,因为动物没有扩大水牛城!

You should only cast to a class that the object really is. 您应该仅将对象强制转换为一个类。

So if you have a Buffalo that extends Animal you can cast it to an Animal (because it is one). 因此,如果您有扩展“动物”的水牛城,则可以将其投射为“动物”(因为它是其中一个)。

But you can't cast an Animal to a Buffalo as not all Animals are Buffalos. 但是您不能将动物投掷到水牛城,因为并非所有动物都是水牛城。

You're telling the compiler (by the explicit cast) to trust you that you're not making errors, so it's ignoring the errors and doesn't detect it in compilation time. 您是在告诉编译器(通过显式强制转换)信任您您没有犯错误,因此它忽略了错误并且在编译时未检测到错误。 That's why you don't get a compilation error . 这就是为什么您不会遇到编译错误的原因 But when the program runs, you'll get an exception since A is not an instance of B . 但是,当程序运行时,您会得到一个异常,因为A 不是 B的实例。 You probably wanted to do: 您可能想做:

A b = (A) new B();

Note that if you remove the explicit cast, you'll get a compilation error (Which is always preferable) because the compiler already knows that you're doing a mistake. 请注意,如果删除显式强制转换,则会出现编译错误 (总是首选),因为编译器已经知道您在做错误。

In the other example, that you think it's the same.. Well.. it's not the same, there, req is an instance of HttpServletRequest . 在另一个示例中,您认为它是相同的..嗯..这是不相同的,那里, reqHttpServletRequest一个实例。

When you do a new A , you cannot cast it to B , given B is a subclass of A (what should otherwise the attributes and the mothods defined in B but not A look like?) 当你做一个new A ,你不能将它转换为B ,因为B是的子类A (又该否则属性和mothods定义B ,但不是A样子?)

In HttpServletRequest request = (HttpServletRequest) req; HttpServletRequest request = (HttpServletRequest) req; , req was created somewhere else, it is a HttpServletRequest req是在其他地方创建的,它是一个HttpServletRequest

Cause HttpServletRequest is a ServletRequest . 原因HttpServletRequestServletRequest In your example A is not necessary a B , could be a A or a C or whatever subclass. 在您的示例中, A不一定是B ,可以是AC或任何子类。

Let see example with animals that is more easier. 让我们来看看动物的例子,它更容易。

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

In main. 在主要。

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

An animal could not be a dog can be a cat or something else like in this case an Animal, then a ClassCastException is thrown. 动物不可能是狗,也可能是猫,或者像本例中的Animal这样的其他东西,然后ClassCastException To avoid this runtimeException you can use instanceof operator. 为了避免此runtimeException,可以使用instanceof运算符。

This doesn't throw an exception because servletrequest is a super interface for HttpServletRequest. 这不会引发异常,因为servletrequest是HttpServletRequest的超级接口。

This is similar to the lines of dynamic polymorphism. 这类似于动态多态性。 If you wrote an interface B and then cast the A object to B it would work. 如果您编写了一个接口B,然后将A对象转换为B,那么它将起作用。

http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html 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