Ability to assign a specific type to a class method that accepts any type and generate a type-specific class **
Now you can ** guarantee the type of member elements at compile time **
Define a generic type
** class class name <type parameter, ...> {class} **
ex: Declare type parameter E public class ArrayList <E> extends AbstractList <E> {
** Type parameter **: Part of the declaration <...> to receive a particular type
Assign an arbitrary type to the instance
** T (Type) ** ・ ** E (Element) ** ・ ** K (Key) **, ** V (Value) **
** Type variable **: The type declared in the type parameter
Instance member argument / return value
Local variable type
Nested type
In generics, ArrayList
** Erasure **: Converting unnecessary type information at runtime to Object type at compile time in this way
** Actual type parameter (type argument) **: Specific type specified when instantiating a generic type (Integer, etc.)
new ArrayList**<Integer>**:
** Parameterized type **: A generic type to which a specific type is assigned by a type argument (such as ArrayList ).
new **ArrayList<Integer>**:
Type parameter constraints
** I want to assume that the method has some arguments **
In the example below, an error will occur because T-type variables x and y do not always have a compareTo method.
Classes such as String, Integer, File that implement the = Comparable interface with compareTo method
//error
public class GenericConstraint <T> {
public int Hoge(T x, T y) {
return x.compareTo(y);
}
}
→ ** Add constraint (boundary type) with type parameter **
<Type parameter extends boundary type, ..>
Type parameters with ingBuilder boundary type are ** converted to boundary type instead of Object type at compile time **
String type etc. that implements Comparable interface can be passed to GenericConstraint class as shown below.
//An example of recognizing the compareTo method
public class GenericConstraint <T extends Comparable<T>> {
public int Hoge(T x, T y) {
return x.compareTo(y);
}Shi
}
Boundary type is ** class / interface can be specified **
extends ** instead of * implements
** Multiple interfaces can be specified **
** Only one class ** (or 0)
** Described in the order of class → interface **
public class MyGeneric <T extends Hoge & Bar $ Foo> {
Generic method constructor
Methods and constructors that can be determined when calling ** types such as arguments / return values and local variables **
Generic methods are ** independent of generic types, so non-generic types can also be defined **
[Modifier]<Type parameters>Return type method name(Argument type Argument name, ...)
[throw phrase]{
Method body
}
Boundary wildcard type
** Covariant **: ** Array ** can assign derived class to base class Child [] can be assigned to Parent [] if Parent / Child has inheritance relationship
Object[] data = new String[5];
Since Object / String has an inheritance relationship, a String array can be assigned to enter the Object type.
Since the actual data of data [1] = 10; is String [], ArrayStoreException
** invariant **: ** Generics ** collection
ArrayList cannot be assigned to ArrayList even if Parent / Child has inheritance relationship
ArrayList <Object> data = new ArrayList <String> (); // Error
//NG example
import java.util.List;
public class GenericBounded {
//List<Parent>Receives and outputs a list of types
public void show(List<Parent> list) {
for (var p : list) {
System.out.println(p.getName());
}
}
}
import java.util.ArrayList;
import java.util.Arrays;
public class GenericBoundedBasic {
public static void main(String[] args) {
var cli = new GenericBounded();
var data1 = new ArrayList<Parent>(Arrays.asList(
new Parent("Frog"), new Parent("Chicken"), new Parent("Dragonfly")));
var data2 = new ArrayList<Child>(Arrays.asList(
new Child("Tadpole"), new Child("Chick"), new Child("Yago")));
cli.show(data1); //OK
//List<Parent>List as a type argument<Child>Type value cannot be passed
cli.show(data2); //Compile error
}
}
Since show is a method that refers to the contents of the list, no value assignment occurs.
→ ** Boundary wildcard ** allows Parent type or its derivative type (covariant)
List type can be passed as an argument of List type
Elements cannot be added or updated
Boundary wildcard type can only reference values with ** boundary type **
import java.util.List;
public class GenericBounded {
//Boundary wildcard
public void show(List<? extends Parent> list) {
for (var p : list) {
System.out.println(p.getName());
}
}
}
Standard library example
ArrayList.java
public boolean addAll(Collection<? extends E> c){
Object[] a = c.toArray();
//Abbreviation
}
Values such as ArrayList , ArrayList type cannot be addedAll to ArrayList type if it is defined as addAll (Collection <E> c"
By using boundary wildcards ** The element type of the list passed as an argument can be CharSequence / its derived type **
Lower bound wildcard type
** Upper bound wildcard : Upper bound type and its subtypes are also allowed ( <? Extends E> **)
** ** Lower bound wildcard : Can pass base type to cangue type = ** contravariant ** ( <? Super T> **)
In the addAll method, the lower bound wildcard type Collection <? Super T> can pass a collection whose elements are ** type T or its higher type **
If addAll did not have a lower bound wildcard type, adding a String type element would have to be ArrayList <String>
When the argument (producer) is just to get the value ** Upper bound wildcard **
For arguments (consumers) that only set a value ** Lower bound wildcard **
java:java.util.Collections.addAll.java
public static <T> boolean addAll(Collection<? super T> c, T... elements) {
boolean result = false;
for (T element : elements)
result |= c.add(element);
return result;
}
//ArrayList<Object>Allows the addition of String type elements for
import java.util.ArrayList;
import java.util.Collections;
public class LowerBoundedBasic {
public static void main(String[] args) {
var list = new ArrayList<Object>();
Collections.addAll(list, "neko", "inu", "tori");
System.out.println(list); //[neko, inu, tori]
}
}
Non-boundary wildcard type
Does not have a border type
Specify as List <?>
Note: To guarantee mold safety
** Cannot call method that takes T as an argument **
** All Ts that are the return values of the method are object type **
import java.util.List;
public class UnBounded {
public static void showList(List<?> list) {
for (var item : list) {
System.out.println(item);
}
//list.add("Hoge");//Since the type is not decided, the value cannot be passed
//list.add(null); //Exceptionally null is OK
// Object obj = list.get(0); //The obtained result is not a String type but an Object type!!
}
}