farmcommand2
farmcommand2

Reputation: 1496

Casting objects in a way that we cast Primitive Data Types

I have three classes: A, AA and Top. A and AA extend Top.

Why is it that this won't compile:

A a = new A();
AA aa = (AA)a;

but this will:

float f = 4.3f;
int i = (int) f;

Upvotes: 4

Views: 643

Answers (3)

shizhz
shizhz

Reputation: 12541

Java is a strong-type programming language, which means to define every variable, you need to specify its type, and for each variable, it can only hold a value belongs to the same type. For primitive types Java also defines the rules how different types can be casted to each other, there's Widening Primitive Conversion(no info loss) and Narrowing Primitive Conversion(info may loss), you can find more details at the official Java docs. So the reason you can do int i = (int) f; is that the conversion rule is defined in Java Spec and Java compiler allows you to do so. You can't do int a = (int) true if you tried, because there's no such a rule to convert boolean type to int.

Type casting rules for reference types are also simple, the compiler only allow you to do type casting A a = (A) b when it thinks the type of b maybe A or some sub-type of A in the type hierarchy, take a look at the following code:

Object b = c;
A a = (A) b;

compiler only knows that b is type Object but has no idea of its specific type, because Object is the root of Java type hierarchy, so the real type of b maybe any type, like type A, so the compiler will allow you to do so. If b actually is not a A, the error can only be found at runtime, when a ClassCastException will be thrown.

On the other hand, the compiler will prevent you to do A a = (A) b when it clearly knows that b is not type A:

class A {}
class B {}

If you have the above definition of type A and B, then compiler has enough information that an instance B is absolutely not type A, so it will give you a compile error of Inconvertible types when you try to do A a = (A) new B(). And this is one of big benefits to use a strong-type programming language: to guarantee type safety (at compile time for Java).

Upvotes: 0

Maulik Doshi
Maulik Doshi

Reputation: 323

You may create cast method in the class you want to cast. Here I have cast type into type A by using a.cast(B b) method.

public class A {
    public int i;
    public  A cast(B b){
        A a = new A();
        a.i=b.i;
        return a ;
     }
}

public class B {
    public int i=10;
}



public class Tester {
    public static void main(String[] args) {
        B b = new B();
        A a= new A();
        a=a.cast(b);
        System.out.println(a.i);
    }
}

Upvotes: 0

Kröw
Kröw

Reputation: 294

Class A and class AA are on the same hierarchy, but they are side by side, so they can not be cast as one another.

Lets say class A was defined as so:

public class A extends Top{

   public A() {

   }

   public void foo(int i) {
      System.out.println(i);
   }

}

And that class AA was defined as so:

public class AA extends Top {

   public AA() {

   }

   public void bar(String s) {

   }

}

Now lets theoretically imagine what would actually happen if you tried to cast an A to an AA and it worked:

A a = new A();
(AA) aa = (AA) a;

Since aa has a static type of AA, Java would let you write code like this:

aa.bar("hi!");

Because the AA class has a bar method, BUT aa has a dynamic type of A, which means that the actual object that the variable aa refers to does not have a method called bar("hi!").

(The static type of an object tells you what methods you can call on it and the dynamic type tells you what methods it actually has.)

So Java would tell aa to do bar("hi!") but aa wouldn't know what to do, because aa does not have the bar method defined.

Upvotes: 1

Related Questions