Monday, 17 September 2007

Raw Types And Erasure Types

Continuing Reading Java Language Specification turned to section Types, Values, and Variables

Can we predict if there are any unchecked warnings in this program?

class Cell {
E value;
Cell (E v) { value=v; }
E get() { return value; }
void set(E v) { value=v; }
}

public class RawTypes {
public static void main(String[] args) {

Cell x = new Cell("abc");
x.value="uK"; // unchecked warning
x.get();
x.set("def"); // unchecked warning
System.out.println(x.get().getClass().getSimpleName());
}
}

Well below statements produces unchecked warnings.Why?
x.value="uK";
x.set("def");

We need to know what is a Raw Type before we answer the above question.Below is a snippet from JLS.

Type Erasure
Type erasure is a mapping from types (possibly including parameterized types and type variables) to types (that are never parameterized types or type variables).

Raw Types:To facilitate interfacing with non-generic legacy code, it is also possible to use as a type the erasure of a parameterized type. Such a type is called a raw type.

More precisely,A raw type is:
The name of a generic type declaration used without any accompanying actual type parameters.

The type of a constructor ,instance method , or non-static field M of a raw type C that is not inherited from its superclasses or superinterfaces is the erasure of its type in the generic declaration corresponding to C

In our code Cell x = new Cell("abc"); is an example of a RawType.

The rules for generating warnings when accessing members or constructors of raw types are as follows:

An invocation of a method or constructor of a raw type generates an unchecked warning if erasure changes any of the types of any of the arguments to the method or constructor.

An assignment to a field of a raw type generates an unchecked warning if erasure changes the field's type.

Always Remember,The type of the member(s) of Inner depends on the type parameter of Outer. If Outer is raw, Inner must be treated as raw as well, as their is no valid binding for T.

For Exampe:
class Outer{
T t;

Inner inner=new Inner();

class Inner {
T setOuterT(T t1) {t = t1;return t;}
}
}

class TExample {
public int size=10;
}

class RawType {

public static void main(String[] args) {

Outer outer=new Outer();
outer.inner.setOuterT(new TExample());
}
}

outer.inner.setOuterT(new TExample()); gives a unchecked warning because Type Of Outer Class is a raw type hence we cannot make Inner class a parameterized type.

Similarly

Class OuterAgain {

Inner inner;

class Inner {
T t;
}
}


public class InnerRawType {

public static void main(String[] args) {

OuterAgain.Inner x = null; // illegal for the same reason.


Hope this explanation helps and please suggest if any.

No comments: