Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java casting in interfaces

Can someone please explain to me how the compiler does not complain in the first casting, but does complain in the second?

interface I1 { }
interface I2 { }
class C1 implements I1 { }
class C2 implements I2 { }

public class Test{
     public static void main(String[] args){
        C1 o1 = new C1();
        C2 o2 = new C2();
        Integer o3 = new Integer(4);

        I2 x = (I2)o1; //compiler does not complain
        I2 y = (I2)o3; //compiler complains here !!
     }
}
like image 837
user711189 Avatar asked Apr 24 '13 07:04

user711189


People also ask

What is casting how it is used in interface?

Casting to an interface allows you to pass/refer to objects with the same behavior. For example, if you wanted to make a report from a bunch of forecasts you could write code like this: /* Collect some forecastable things */ List<Forecastable> forecastables = Arrays.

Can a class be cast to an interface?

If you have a concrete class, you can cast it to the interface. If you have an interface, it is possible to cast to the concrete class.

Can we create body in interface?

There can be only abstract methods in the Java interface, not the method body. It is used to achieve abstraction and multiple inheritance in Java. In other words, you can say that interfaces can have abstract methods and variables. It cannot have a method body.

Can an interface be a reference type?

An interface is a reference type in Java. It is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface.


2 Answers

When you cast o1 and o3 with (I2), you tell the compiler that the class of the object is actually a subclass of its declared type, and that this subclass implements I2.

The Integer class is final, so o3 cannot be an instance of a subclass of Integer: the compiler knows that you're lying. C1 however is not final, so o1 could be an instance of a subtype of C1 that implements I2.

If you make C1 final, the compiler will complain too:

interface I1 { } interface I2 { } final class C1 implements I1 { } class C2 implements I2 { }  public class Test{      public static void main(){         C1 o1 = new C1();         C2 o2 = new C2();         Integer o3 = new Integer(4);          I2 y = (I2)o3; //compiler complains here !!         I2 x = (I2)o1; //compiler complains too      } } 
like image 66
WilQu Avatar answered Sep 23 '22 10:09

WilQu


According to JLS chapter 5

5.5.1. Reference Type Casting

Given a compile-time reference type S (source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules. If T is an interface type:

If S is not a final class (§8.1.1), then, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs.

Otherwise, the cast is always legal at compile time (because even if S does not implement T, a subclass of S might).

If S is a final class (§8.1.1), then S must implement T, or a compile-time error occurs.

like image 33
maba Avatar answered Sep 21 '22 10:09

maba