Background information
to understand
generic classes
- The
importance of
data type
information
in programming:
- The data type of
a variable is
of
utmost importance to
the Java compiler when
it
translates
the program statements
- Some
uses:
- The data type is used to
determine if
an operation is
permitted:
int a;
double b;
a = b; // Not permitted without casting
|
- The data type can
determine the
meaning of an
operation:
int a, b; a + b means: addition
String a, b; a + b means: concatenation
|
|
|
|
Intro to
generic classes
- Consider the
following
class that
stores a
String object:
public class StringStore
{
private String data; // variable of String type
public StingStore(String data)
{
this.data = data;
}
public String getData() // return String type
{
return this.data;
}
}
|
- We can store
Strings
in a StringStore object:
StringStore a = new StringStore("Hello");
System.out.println(a.getData()); --> Hello
System.out.println(a.getData() + a.getData()); --> HelloHello
|
|
DEMO:
06-generics/01-intro/Demo.java
+ StringStore.java
Intro to
generic classes
- Ths StringStore class
can
only
store
String objects:
public class StringStore
{
private String data; // variable of String type
public StingStore(String data)
{
this.data = data;
}
public String getData() // return String type
{
return this.data;
}
}
|
- If we try to
store an
Integer,
we get a compile error:
StringStore a = new StringStore(12345);
|
|
DEMO:
06-generics/01-intro/Demo1.java
+ StringStore.java
Intro to
generic classes
- Consider the
another
class that
stores a
Integer object
(using a wrapper class):
public class IntegerStore
{
private Integer data; // variable of Integer type
public IntegerStore(Integer data)
{
this.data = data;
}
public Integer getData() // return Integer type
{
return this.data;
}
}
|
- We can use IntegerStore class
to store
Integer objects:
IntegerStore a = new IntegerStore(12345);
System.out.println(a.getData()); --> 12345
System.out.println(a.getData() + a.getData()); --> 24690
|
|
DEMO:
06-generics/01-intro/Demo2.java
+ IntegerStore.java
Can we write
1 class to store
every possible
object type ???
-
Observations:
- The classes
StringStore and
IntegerStore
store
object (reference) types
- The code look
very very very similar...
|
-
Question:
|
Review: the
Object class
- The designers of the
Java programming language
has created the
following
inheritance hierachy:
|
Intro to
generic classes
-
Idea:
use the
Object class
since
every class is
a
subclass
of Object:
public class ObjectStore
{
private Object data; // variable of Object type
public ObjectStore(Object data) // Can receive any ref type
{
this.data = data;
}
public Object getData() // return Object type
{
return this.data;
}
}
|
- The output of this
program is:
ObjectStore a = new ObjectStore("Hello");
ObjectStore b = new ObjectStore(12345);
System.out.println(a.getData()); --> Hello // Work !
System.out.println(b.getData()); --> 12345
|
|
DEMO:
06-generics/01-intro/Demo3.java
+ ObjectStore.java
Looks good ????
try Demo4.java !!
Intro to
generic classes
-
Idea:
use the
Object class
since
every class is
a subclass
of Object:
public class ObjectStore
{
private Object data; // variable of Object type
public ObjectStore(Object data)
{
this.data = data;
}
public Object getData() // return Object type
{
return this.data;
}
}
|
-
However:
this program generate a
bad operand types for + operator
error:
ObjectStore a = new ObjectStore("Hello");
ObjectStore b = new ObjectStore(12345);
System.out.println(a.getData() + a.getData()); // Error
System.out.println(b.getData() + b.getData()); // Error
|
|
DEMO:
06-generics/01-intro/Demo4.java
+ ObjectStore.java
Why
won't
Demo4.java
compile ???
How can you
fix
Demo4.java ???
How can you
fix
Demo4.java ???
- Solution:
public class Demo4
{
public static void main(String[] args)
{
ObjectStore a = new ObjectStore("Hello"); // a String
ObjectStore b = new ObjectStore( 12345 ); // an Integer
System.out.println( (String) a.getData()
+ (String) a.getData() );
System.out.println( (Integer) b.getData()
+ (Integer) b.getData() );
}
}
|
|
DEMO:
demo/06-generics/01-intro/Demo5.java +
ObjectStore.java
But can you
fix
Demo4.java
automatically ???
Generic class:
parameterized classes
-
Generic class:
- A
generic class is
a
parameterized
class
where the
parameters
(plural) are
always
object types
|
-
Review:
how to define
a
non-generic class:
public class ClassName
{
....
}
|
-
Syntax to
define a
generic (= parameterized) class:
// T1, T2, .. are object type parameters
public class ClassName<T1,T2,..>
{
.... // We can use T1, T2, .. as type specifier here
}
|
|
Example of a
generic
(parameterized) class
- Example of a
generic class:
public class GenericStore<T> // T is the type parameter
{
private T data; // variable of T type
public GenericStore(T data)
{
this.data = data;
}
public T getData() // returns T type variable
{
return this.data;
}
}
|
- Important facts:
- The Java compiler will
remember the
places where
the
generic type parameter T
were used
- The
generic type parameter T
tells the
Java compiler to
place
the correct
cast operation
at some
result
before
using it.
|
|
- When the parameter type is
<T>:
public class GenericStore<T> // T is the type parameter
{
private T data; // variable of T type
public GenericStore(T data)
{
this.data = data;
}
public T getData() // returns T type variable
{
return this.data;
}
}
|
The Java compiler will:
- Replace
every occurence of
<T>
by:
Object
|
|
How the
Java compiler use
a generic class
- When you
define an
variable of a
generic class, you
specify the
object type
parameter
along with the
class name
as follows:
GenericsStore<String> a = new GenericsStore<String>();
GenericsStore<Integer> b = new GenericsStore<Integer>();
|
- The
result will be:
- The Java compiler will
remember the
parameter type of
each variable
and
-
Insert the
proper
casting operation
before
using the
value returned
by their methods !
|
Example:
Expression: a.getData() + a.getData()
Because getData() returns type <T> and <T> = <String>
Java compiler will insert (String):
--> (String)a.getData() + (String)a.getData()
|
|
DEMO:
demo/06-generics/01-intro/Demo6.java +
GenericStore.java
Postscript
- The parameters of
a generic class
must be
object (reference) types
Therefore:
- You
cannot
define
generic class
variables using
primitive types:
GenericStore<int> a = new GenericStore<int>(); // Illegal !
|
- Use a
wrapper class
if you
need to use a
primitive type
|
- You can use this
short hand notation
to
define a
generic class
variable:
GenericStore<Integer> a = new GenericStore<>();
|
The Java compiler can
infer the
second parameter
😆
- Commonly
parameter names used are:
T
(Type),
E (Element),
K (Key) and
V (Value)
|
Post-postscript
- Interfaces behaves
like classes
- You can also define
generic (parameterized)
interfaces
- Example: the
non-generic ComparableTing
interface was:
public interface ComparableThing
{
public int compareTo( ComparableThing x );
}
|
- When we parameterize
the ComparableThing<T>
with type
T, we can
use the
type T
to declare the
parameter variable:
public interface ComparableThing<T>
{
public int compareTo( T x );
}
|
-
Implementing a
parameterized interface
is
very tricky
and
beyond the
scope of
CS 171... ---
see Chapter 19.5
in Liang's book
(E.g.:
selectionSort
in
demo/06-generics/02-comparable - not part of CS171)
|
❮
❯