Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException vs. "cannot cast" compilation error

Studying for my OCA Java SE 7 Programmer I exam, so newbie question. I have an example question I do not understand. The following code compiles, but gives a ClassCastException at runtime:

interface Roamable {
}

class Phone {
}

public class Tablet extends Phone implements Roamable {
    public static void main(String... args) {
        Roamable var = (Roamable) new Phone();
    }
}

When I change Roamable var = (Roamable) new Phone(); into Roamable var = (Roamable) new String(); I get a compilation error right away.

Two questions:

  1. Why does the code above compile at all? Phone seems unrelated to Roamable to me?
  2. Why does the code compile with new Phone(), but doesn't it compile with new String()?
like image 820
luukburger Avatar asked Nov 10 '13 21:11

luukburger


People also ask

How do I resolve Java Lang ClassCastException error?

How to handle ClassCastException. To prevent the ClassCastException exception, one should be careful when casting objects to a specific class or interface and ensure that the target type is a child of the source type, and that the actual object is an instance of that type.

Is ClassCastException a runtime error?

If a ClassCastException is one of the most common exceptions in Java. It is a runtime exception that occurs when the application code attempts to cast an object to another class of which the original object is not an instance.

Is class cast exception a compiler error?

If the program were compiled and the program run, every evaluation of this expression would throw a ClassCastException. There- fore, this is expression is deemed a compile-time error, a syntax error, and the expression will not be compiled.

What is ClassCastException in Java?

Introduction. ClassCastException is a runtime exception raised in Java when we try to improperly cast a class from one type to another. It's thrown to indicate that the code has attempted to cast an object to a related class, but of which it is not an instance.


2 Answers

Why does the code above compile at all? Phone seems unrelated to Roamable to me?

yes because Roamable is an interface it might cause a Run-time exception but not compile time exception, because even if Phone doesn't implement Roamable, a subclass of Phone might, hence the compiler has no way to know it but at the Run time.

It is already defined in java language specification. Check out my answer here.

Why does the code compile with new Phone(), but doesn't it compile with new String()?

Because class String is declared as public final class in java.lang package. As specified in jls 8.1.1.2 final class section: a class declared as final can't be extended and hence it won't have any subclass. So, the compiler already knows that String can't be extended: hence no subclass's existence is possible to implement interface Roamable

Edit: (With response to your below comment)

Let us assume that B is a subclass of A which implements an interface T.

Now an statement :

   T t = (T)new A();

is essentially same as:

   A aObj = new A() ;
   T t = (T)aObj ; // a run-time exception happen

before running into conclusion, let us do the same thing with an object of B:

   A aObj = new B();
   T t = (T)aObj; // no exception happen.

so, the real reason with super class and sub class here is the reference. The aObj class in this second code example is also an instance of class A but it is also an instance of class B which has implemented T.

like image 158
Sage Avatar answered Sep 28 '22 16:09

Sage


String is final so there is no way it can be cast to a Roamable.

like image 21
JamesB Avatar answered Sep 28 '22 16:09

JamesB