Generics
Concept:
Generics make an object that uses a certain class, enforce that only the (sub)class(es) of a particular type can go into a certain object / method. text
Rationale:
In the past developer used to work with objects in which Objects go in, and were casted to the right type to enable use of a particular class' methods. This made the object being used very prone to ClassCastExceptions. With Generics, the compiler forces that only objects of the defined type can be used with a certain object.
Type erasure:
Behind the scenes the compiler changes the Generic Symbols used, like T/K/V to Objects and adds the relevant casts for the code to work with the type of the erased class.
Generic Classes
Generic methods
Defined on
class level
Example:
Public class SomeGenericClass<T> {}
SomeGenericClass<String> s = new SomeGenericClass<>();
Bounds
Example with return type:
public <T> SomeRandomGenericClass<T> doSomething(T t) {
System.out.println("You put in a" + t);
return new SomeRandomGenericClass<T>;
}
Example without return type:
public <T> void doSomethingElse(T t) {
System.out.println("Here's a " + t);
}
Concept:
Generic objects generally are treated like 'Object' class due to the type erasure, to solve this, bounds have been introduced
Upper bounded wildcard
unbounded wildcard
Lower bounded wildcard
Use:
Specifies that any type that is a superclass of ? can be used in the generic. All objects being passed to the generic are treated like a superclass of ?.
Use:
Specifies that any type is okay. Generic types using this wildcard are treated like a class from 'Object'
Syntax:
List<?> list = new ArrayList<>();
Use:
Specifies that any type that extends ? can be used in the generic. Note that using upper bound generics, make them immutable by default.
Syntax:
List<? super Number> list = new ArrayList<>();
Syntax:
List<? extend Number> list = new ArrayList<>();