简体   繁体   中英

Runtime exception when doing a Casting

I am getting a Runtime exception when doing a Casting as shown below

Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B at 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();
    }

}

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.

You can check that using 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

Scenario that is working:

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

The second statement 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 . That's why you can again cast it back to B .

You're not doing the same thing.

In your second example req is an instance of HttpServletRequest.

In your first example A is not an instance of B.

A is not an instance of B, hence you can't downcast in your scenario.

Consider this, A is Animal and B is Buffalo.

Now, Buffalo extends Animal.

Then, in your code, you do:

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 . 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 .

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?)

In HttpServletRequest request = (HttpServletRequest) req; , req was created somewhere else, it is a HttpServletRequest

Cause HttpServletRequest is a ServletRequest . In your example A is not necessary a B , could be a A or a C or whatever subclass.

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. To avoid this runtimeException you can use instanceof operator.

This doesn't throw an exception because servletrequest is a super interface for 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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