Java Reference
In-Depth Information
You cannot pass an
Integer
to the
set()
method. The compiler will generate an error. If you want to use the
Wrapper
class to store an
Integer
, your code will be as follows:
Wrapper<Integer> idWrapper = new Wrapper<Integer>(new Integer(101));
idWrapper.set(new Integer(897)); // OK to pass an Integer
Integer id = idWrapper.get();
// A compile-time error. You can use idWrapper only wth an Integer.
idWrapper.set("hello");
Assuming that a
Person
class exists that contains a constructor with two parameters, you store a
Person
object in
Wrapper
as follows:
Wrapper<Person> personWrapper = new Wrapper<Person>(new Person(1, "Chris"));
personWrapper.set(new Person(2, "Laynie"));
Person laynie = personWrapper.get();
The parameter that is specified in the type declaration is called a
formal type parameter
; for example,
T
is a formal
type parameter in the
Wrapper<T>
class declaration. When you replace the formal type parameter with the actual type
(e.g. in
Wrapper<String>
you replace the formal type parameter
T
with
String
), it is called a
parameterized type
.
A reference type in Java, which accepts one or more type parameters, is called a generic type. A generic type is mostly
implemented in the compiler. The JVM has no knowledge of a generic type. All actual type parameters are erased
during compile time using a process known as
erasure
. Compile-time type-safety is the benefit that you get when you
use a parameterized generic type in your code without the need to use casts.
Supertype-Subtype Relationship
Now, let's play a trick. The following code creates two parameterized instances of the
Wrapper<T>
class, one for the
String
type and one for the
Object
type:
Wrapper<String> stringWrapper = new Wrapper<String>("Hello");
stringWrapper.set("a string");
Wrapper<Object> objectWrapper = new Wrapper<Object>(new Object());
objectWrapper.set(new Object()); // set another object
// Use a String object with objectWrapper
objectWrapper.set("a string"); // ok
It is fine to store a
String
object in
objectWrapper
. After all, if you intended to store an
Object
in
objectWrapper
,
a
String
is also an
Object
.
Is the following assignment allowed?
objectWrapper = stringWrapper;
No, the above assignment is not allowed. That is,
Wrapper<String>
is not assignment compatible to
Wrapper<Object>
. To understand why this assignment is not allowed, let's assume for a moment that it was allowed.
You would be able to write code like the following:
// Now objectWrapper points to stringWrapper
objectWrapper = stringWrapper;