Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Customs class instance can't cast to String. Why? [duplicate]

Tags:

java

Why the instance of A can cast to List but can not cast to String?

class A{}
...
A a = new A();
List list = (List)a;   //pass
String s = (String)a;  //compile error 
like image 589
DeanLin Avatar asked Jan 27 '16 12:01

DeanLin


3 Answers

Quoting JLS:

It is a compile-time error if, for any two classes (not interfaces) Vi and Vj, Vi is not a subclass of Vj or vice versa.

String and A are unrelated classes, so it is a compile-time error. List is an interface, so that does not cause the same error.

Note that your assertion

the instance of A can cast to List

Is not quite correct: A cannot be cast to List; it is just a runtime failure, not a compile-time failure.

like image 156
Andy Turner Avatar answered Nov 12 '22 10:11

Andy Turner


The compiler, according to the specification, only takes the declared type of a into account when it does these checks for casts.

So, you write:

A a = new A();

But the compiler only considers

A a; // = <something>;

So it knows that a cannot be a String, since a class can have only one superclass (no multiple inheritance), there can't be a subclass of class A that is also a String.

But for interfaces this isn't true. So while we know that class A doesn't implement List, there could be a class B defined like this:

class B extends A implements List {}

And since the compiler only considers the declared type, it must assumes that it is also possible the you assigned new B() to a.

So, because a subclass of A could implement the interface List, the compiler can't assume that the cast to List always fails.

Of course the cast will fail in practice though - at runtime. But not at compile time.

like image 6
Erwin Bolwidt Avatar answered Nov 12 '22 10:11

Erwin Bolwidt


A class in Java can only be cast to one of its super types, or one of the interfaces on one of its super types.

In your case, class A is not a subclass of String. Therefore A cannot be cast to a String. Also, String is a final class, so you cannot write a class A that could be cast to a String.

Java already recognizes the need to easily display classes as Strings, especially for debugging / logging purposes. To satisfy this need, the Object class comes with a toString() method. Since all Java classes extend from the Object class, all Java classes contain an implementation of the toString() method.

It is important to remember that the existence of a toString() method doesn't mean that A is a String, rather it means that you can get a String from A that somewhat describes the A instance. If you find that the provided description is lacking for your purposes, you may override A's toString() method an return a better description, like so

@Override
public String toString() {
  return "my better description";
}

As the override is written in Java, you can also include any variable or other item that you can eventually turn into a String (which since all Objects have toString() includes nearly anything).

like image 1
Edwin Buck Avatar answered Nov 12 '22 11:11

Edwin Buck