Java Generics

Generics


What are Generics in Java? Good question. Looking around the web one would find explanations and definitions that sound good... but... don't really say anything.

I've read...       It extends the java type system.    ...It does do that.       It enforces Type Safety.   ...It does that too. But that's what it does... not what it is.


The definition seems to be more complex than the implementation... In other words... it is easier to show someone how to use Generics than it is to explain what it is.

In my view the definition is in the name. Generic·s. It provides the the ability to create classes, interfaces and methods that deal in generic data types... more specifically... data types that are determined at compile time.

In a nutshell... allowing classes to become a Generic Type...

allows them to be Polymorphic. .

CREATED 2020-10-03 12:37:41.0

010-00-03-50

UPDATED 2020-10-07 09:59:22.0

The Declaration...


class ClassName<T1 [, T2 [, ...] Tn]>{} class MyClass<T>{    ... } MyClass<String> mc = new MyClass<String>();

Declare a Generic Class using Type Parameters...

...T is a generic type (See Type Parameters) and the number following it is the numer of that type.

A more realistic example:



Instantiate a generic class with Type Arguments...

CREATED 2020-10-11 11:26:15.0

010-00-03-5E

UPDATED 2020-10-11 11:26:26.0

The Type Parameter


Type Parameters are encased in angle brackets<T1[, T2[, T3[, Tn]]]>.

Type parameters are single uppercase letters. The list is open ended but these are some common types... Use a comma to indicate multiple types e.g. <K,V>

  • E - Element - an element of Java Collections.
  • K - Key - the Key in a map.
  • V - Value - the value in a map.
  • N - Number - a number.
  • T - Type - a general type or the first type parameter.
  • S - Type - a general type as the second type paramter.
  • U - Type - a general type as the third type paramter.

To indicate more than one parameter of the same type use a reference number e.g. T1, T2, etc.

As you probably noticed... the type parameter is not the same as a type argument. There is a difference...

  • Type Parameter - is the generic type as defined in the class... public Class Foo<T>{    ... }

  • Type Argument - is the real type that is passed when the class is instantiated Foo<String> f = new Foo<>();

Some programmers don't notice.

CREATED 2020-10-03 12:32:39.0

010-00-03-4F

UPDATED 2020-10-07 09:59:22.0

The Diamond Operator


List<String> strings = new ArrayList<String>(); List<String> strings = new ArrayList<>();

Generics was introduced in Java 1.5 or Java 5. But after a little growing it became apparent that the Type parameter had to be passed twice. Once for the Type reference and once for the class instantiation...

So in Java 1.7 or Java 7 the folks at CAFE BABE came out with the diamond operator. Since the types are already given in the reference argument they could be copied to the class call...

CREATED 2020-10-05 08:22:34.0

010-00-03-51

UPDATED 2020-10-07 09:59:21.0

Raw Types


p>In Generics you declare a class type by passing the type when the class in instantiated... List<String> stringList = new ArrayList List rawList = new ArrayList(); List<String> stringList = new ArrayList><(); List rawList = stringList; List rawList = new ArrayList(); List<String> stringList = rawList;

In Generics you declare a class type by passing the type when the class in instantiated... List<String> stringList = new ArrayList List rawList = new ArrayList(); List<String> stringList = new ArrayList><(); List rawList = stringList; List rawList = new ArrayList(); List<String> stringList = rawList; < >();

This would create an ArrayList of type String.

A Raw Type is a type that has been declared but the Type parameter has been omitted.

Now... you can assign a raw type to a parameterized type...


But the compiler will complain about an unchecked conversion if you do it the other way around (assign a parameterized type to a raw type)...


Much of this is for legacy code.

< >();

This would create an ArrayList of type String.

A Raw Type is a type that has been declared but the Type parameter has been omitted.

Now... you can assign a raw type to a parameterized type...


But the compiler will complain about an unchecked conversion if you do it the other way around (assign a parameterized type to a raw type)...


Much of this is for legacy code.

CREATED 2020-10-05 08:35:14.0

010-00-03-52

UPDATED 2020-10-07 09:59:21.0

Generic Methods


public <K,V> boolean Set(K key, V value){    ... } public <T> T Set(T value){    ... } boolean isSet = <classReference>.<String, String>set("Key", "Value"); boolean isSet = <classReference>.set("Key", "Value");

A methods parameters can be generically parameterized the same way as types for classes and interfaces can. There is a slight difference in the sytax... -> the Type parameter needs to appear before the return type to indicate what types you are using...



In fact... even the return type can be parameterized...



Technically, to call a generic method you pass the Type Arguments with the method call...

However... the java compiler will derive or infer the types from the arguments you pass... so you can omit the Type Parameters in the method call...

CREATED 2020-10-05 09:44:13.0

010-00-03-53

UPDATED 2020-10-07 09:59:20.0

Bounded Types


public class Widget<T extends Person>{    ... } public class Widget<T super Employee>{    ... }

Paramterized Types can be bounded to restrict the types they can represent to a specific class and any of its decendants.

Generally all Type Parameters extend Object so a type argument can not be primative like an int or char, it has to be a class like ArrayList.

Using the extends key word you can limit the classes the Type Parameter can represent. This is called Upper bounded.

Example: We want to restrict the type the widget class can except to the Person class...



Now, since Employee and Customer both extend Person, they would be included as allowable types.

To go the other way we use the super keyword...



Now, since Person is the super class of Employee... Employee and Person will be allowable arguments but Customer will not. This is called lower bounded public class Widget<T extends Person & wantable & doable>{    ... }

You can also extend to interfaces or a class and interfaces. However, the class has to be listed first.



CREATED 2020-10-06 05:10:37.0

010-00-03-54

UPDATED 2020-10-07 09:59:19.0

Wild Cards


The wild card <?> is for when you want to be super generic and allow all types to play in raindeer games... this really means you are NOT going to declare a type at all.

So... dont't the T, the E, the K, etc. do all that?

Actually no. In Java... all classes implicitly extend Object.    "Implicitly" as in goes without saying.

So the way this works out is... some classes... let's call them Real Classes... actually say they extend Object in the class declaration...

Or they say they extend a class that extends Object...

Or they say they extend a class that extends a class that extends object...

Or they...

you get the point!

While other classes... lets call them little classes... don't actually say they extend object. Instead they rely on the goes without saying or implicit part.

So if we have a List<Object> declaration... this would include all Real classes... or the classes that say they extend Object. But not the little classes... those that don't actually say it.

By the same token if we use the wild card... List<?> we would include all of the classes from both groups... real classes and little classes.

Wild cards can be used in upper and lower bounds the same as the other Type Parameters can with the extends and super key words.

CREATED 2020-10-06 07:09:55.0

010-00-03-55

UPDATED 2020-10-06 07:10:04.0

Type Erasure


So how does the java compiler know what to do with all this generic stuff? That's where type erasuer comes in.

Type Erasure is really type swapping. Kind of a bait and switch.... the compiler replaces all the Generic references with the real classes that they represent... in the process... it enforces type saftey.

CREATED 2020-10-08 05:48:00.0

010-00-03-57

UPDATED 2020-10-08 05:48:13.0

Terms


Terms:

None-Refiable Type - A type whose type information has been removed at compile time due to type

Refiable Type - A type whose type information is available at runtime .

Type Erasure - When the compiler makes the substitution from the Generic type to the real type at compile time.

CREATED 2020-10-07 10:02:35.0

010-00-03-56

UPDATED 2020-10-07 10:02:44.0

Knowledge

L
I
N
K
S

DBID: db.wam

Page Server: Ithica

©2012 Leistware Data Systems

      Hello anonymous