2

I'm looking at casting in Java, and specifically casting with interfaces. Suppose I have an interface I, that defines a method jump, i.e.:

interface I{
    public void jump();
}

Additionally suppose I have 3 other classes, A, B and C. A implements I. B does not. However, C extends B and implements I.

class A implements I {
   public void jump(){
      System.out.print("A is jumping");
   }
}
class B { } 
class C extends B implements I {
    public void jump(){
        System.out.print("C is jumping");
    }
}

Now if I try to assign an object of type A to an I, there is no problem and I do not even need a cast. I.e.:

I i = new A();

is OK no need to cast.

Presumably this is because the compiler knows that A implements I. Furthermore, if I try to this:

A mya = new A();
I i = mya;

No problems, even though mya could be referencing a subclass of A. But AFAIK that's OK since the compiler knows that every sub class of A must implicitly implement the jump method and therefore the interface A.

However, if I try to assign an object of type B to an I, then I do need a cast. e.g.

B myb = new B();
I i = (I)myb;

Presumably this is because the compiler knows that B does not implement I. However, since B could refer to a subclass which does implement I, then you are allowed to cast to I. So far so good. Now here's my question: If I want to assign an object of type B that refers to an object of type C (which implements I) to an I then we require a cast. Why is that? E.g.

B b = new C();
I myI = b; //Won't compile this needs a cast
I myI = (C)b; // This will compile
myI = (I)b; // This will also compile

Why doesn't the compiler understand that B is referring to a C that implements I?

Presumably it's to do with the fact that B could refer to a B which doesn't actually implement I but why is it that the compiler doesn't know that? Presumably the compiler is limited to the information that is only available on each line? It can't run through your program and see that b is in fact pointing to a C? If that is correct can someone point me in the direction of some literature on how Java compilers work and what exactly are their limitations?

2 Answers 2

6

Presumably this is because the compiler knows that B does not implement I, however since B could refer to a subclass which does implement I then you are allowed to cast to I.

Not exactly. The compiler will let you cast B however you want. That doesn't mean you won't get a ClassCastException at runtime. (Your code will work this time, but the compiler won't prevent you from making bad casts.)

Why doesn't the compiler understand that B is referring to a C that implements I? Presumably it's to do with the fact that B could refer to a B which doesn't actually implement I but why is it that the compiler doesn't know that.

Because you told it to treat the object as a B when you declared B b = new C();

Presumably the compiler is limited to the information that is only available on each line? It can't run through your program and see that b is in fact pointing to a c?

It has access to the rest of the code. It's just doing what you told it to do: treat b as an object of class B.

Sign up to request clarification or add additional context in comments.

1 Comment

Plus one for "told it to treat"
-1

In this particular case, compiler has the ability to determine that b actually refers to an object of C. However language creators chose not to make the the compiler so smart.

In practical scenario, actual object which b refers to, would not be so localized and so compile time determinable. So it was chosen not to make the compiler be over-smart which does not solve practical scenarios.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.