(OOP8) Java Generics

(OOP8) Java Generics

When generics were introduced in JDK 5, they brought about changes to many of the classes and methods of the core Java API. Through the use of generics, it is possible to create classes, interfaces and methods that will work in a type-safe manner for several types of data.

Parameterized Types

Generics are often referred to has parameterized types, where you can create classes, methods and interfaces that have the type of data they work with specified as a parameter.
class Something<T> { T object; // declare an object of type T. // pass the constructor a reference to // an object of type T. Something (T object) { this.object = object; } // return object. T getObject() { return this.object; } // show type of T. void showType() { System.out.println("The type of <T> is: " + object.getClass().getName()); } }

Multiple Parameters

class TwoTypes<T, V> { T objOne; V objTwo; TwoTypes(T objOne, V objTwo) { this.objOne = objOne; this.objTwo = objTwo; } void showTypes() { System.out.println("Type of <T>: " + objOne.getClass().getName()); System.out.println("Type of <V>: " + objTwo.getClass().getName()); } }

Autoboxing and Unboxing

Generics do not utilize primitive types (such as int, double, etc.) as type parameters. When declaring variables in these contexts, Java will automatically convert the type to its corresponding wrapper class (a process called autoboxing).
[If a conversion goes the other way, it’s called unboxing.]

Bounded Types

Sometimes, we want to limit the types utilized to a certain constraint, such as int, float, double, etc. To do so, we can utilize generic types that extend classes.
class StatisticsYo<T extends Number> { T[] numbers; StatisticsYo(T numbers) { this.numbers = numbers; } double average() { double sum = 0.0; for (T x : numbers) sum += x.doubleValue(); return sum / numbers.length; } }

Generic Methods & Interfaces

class Something { static <T extends Comparable<T>, V extends T> boolean isIn(T x, V[] y) { for (int i = 0; i < y.length; i++) if (x.equals(y[i])) return true; return false; } }
interface MinMax<T extends Comparable<T>> { T min(); T max(); } class MyClass<T extends Comparable<T> implements MinMax<T>> { T[] values; public T min() { ... } public T max() { ... } }

Wildcard Arguments

boolean sameAverage(StatisticsYo<?> obj) { if (this.average() == obj.average()) return true; return false; } // upper bounds specified using <? extends superclass>. // lower bounds specified using <? super subclass>.