Java basic advanced knowledge - generics

I. generic

(1) What is generics

The concept of generics

  • Java generics is a new feature introduced in Java JDK 5. Generics provides a compile time type security monitoring mechanism, which allows us to detect illegal type data structures at compile time.
  • The essence of generics is parameterized type, that is, the data type being manipulated is specified as a parameter.

Benefits of generics

  • Type safety
  • Elimination of cast of mandatory type
  • It can operate many different data types to achieve the purpose of code reuse

(2) Generic class, interface

Generic class

  • Definition syntax of generic classes

    class name < generic ID, generic ID,... >{
    	private generic identifier variable name;
    }
    
  • Common generic identifiers: T, E, K, V

  • Using grammar
    Class name < specific data type > object name = new class name < specific data type > ();

details

  1. When a generic class creates an Object, if no type is specified, it will operate according to the Object type;
  2. Generic parameters can only refer to data types and String types, and basic types are not supported;
  3. Generic types can be seen logically as many different types, but in fact they are the same type;

Deriving subclasses from generic classes

  • The subclass is also a generic class, and the generic types of subclass and parent class should be the same
    class Child<T> extends Parent<T>
    The subclass is a generic type. If the generic type of the parent is not specified, the generic type used for overriding the method of the parent is Object
  • The subclass is not a generic type, and the parent class should specify the generic data type
    class Child extends Parent<String>

generic interface

  • Definition syntax of generic interface

    Interface interface name < generic ID, generic ID,... >{
    	Generic identity method name ();
    }
    
  • The class that implements the generic interface is not a generic type. You need to explicitly specify the generic type of the interface

  • The class implementing the generic interface is generic, and the generic types of the interface and the class should be consistent

  • Implementation classes can extend generics, but they must include the generic types of interfaces

(3) Generic methods

  • A generic class indicates the specific type of a generic when instantiating a class.
  • A generic method indicates the specific type of the generic when calling a method.

grammar

	Modifier < T, e,... > return value type method name (parameter list) {...}
public <E> E getTestString(List<E> list) {
	return list.get(0);
}
  • Only methods that contain generic lists are generic methods.
  • Generic methods can make methods independent of classes.
  • If static methods want to use generic capabilities, they must be coarsely made generic.

Generic methods and variable parameters

public <E> void print(E... e){
	for(E el : e){
		System.out.println(el);
	}
}

(4) Type wildcard

What is type wildcard

  • The type wildcard usually uses "?" Instead of specific type arguments.
  • Therefore, a type wildcard is a type argument, not a type parameter.
public static void showBox(Box<?> box){
	// Use? Instead of specific generic types
	Object o = box.getBox();
	...
}

Upper limit of type wildcards

  • grammar
    Class / interface <? Extends argument type >
    The type of the generic type is required. It can only be an argument type or a subclass type of an argument type.
public class MinCat extends Cat {
	
	public void showCat(ArrayList<? extends Animal> list) {
		// The upper limit of the type wildcard cannot be filled with elements because the parameter is not filled with elements? Specific types of
		//list.add(new Animal()); / / an error is reported
		//list.add(new Cat()); / / error
		//list.add(new MinCat()); / / error
		list.forEach(i->System.out.println(i));
	}
	
	// Test pass
	@Test
	public void testFun() {
		ArrayList<Animal> animalList = new ArrayList<>();
		animalList.add(new Animal());
		animalList.add(new Animal());
		animalList.add(new Animal());
		showCat(animalList);
		
		ArrayList<Cat> catlList = new ArrayList<>();
		catlList.add(new Cat());
		catlList.add(new Cat());
		catlList.add(new Cat());
		showCat(catlList);
		
		ArrayList<MinCat> minCatList = new ArrayList<>();
		minCatList.add(new MinCat());
		minCatList.add(new MinCat());
		minCatList.add(new MinCat());
		showCat(minCatList);
	}

}

Lower limit of type wildcard

  • grammar
    Class / interface <? Super argument type >
    The type of the generic type is required. It can only be an argument type or a parent type of an argument type.
	public void showAnimal(ArrayList<? super Cat> list) {
		// Only elements whose parent class is Cat can be populated
		list.add(new Animal());	// error
		list.add(new Cat());
		list.add(new MinCat());
		list.forEach(i->System.out.println(i));
	}
	
	@Test
	public void testFun1() {
		ArrayList<Animal> animalList = new ArrayList<>();
		animalList.add(new Animal());
		animalList.add(new Animal());
		animalList.add(new Animal());
		showAnimal(animalList);
		
		ArrayList<Cat> catlList = new ArrayList<>();
		catlList.add(new Cat());
		catlList.add(new Cat());
		catlList.add(new Cat());
		showAnimal(catlList);
		
		ArrayList<MinCat> minCatList = new ArrayList<>();
		minCatList.add(new MinCat());
		minCatList.add(new MinCat());
		minCatList.add(new MinCat());
		// Only Cat or Cat's parent class can be used as an argument
		showAnimal(minCatList);	// error
	}
  • Call the method with the lower limit of the type wildcard, and the argument passed can only be the type of the argument or its parent type.
  • Fill the element in the method. The filled element can only be a subclass of the argument type (the argument type is the type of the parent class).
  • The filled element does not guarantee the constraint requirements of the data type.

(5) Type erase

concept
Generics is a concept introduced in Java 5. Before that, there was no generics. However, generics code can be very compatible with previous versions of code. That's because the generic information only exists in the code compilation stage. Before entering the JVM, the generic information will be erased, which we call type erasure.

Unlimited type erase

@Test
public void testFun4() {
	// Generic type not specified
	Erasure e1 = new Erasure();
	// Obtain Class object of bytecode file of Erasure Class by reflection
	Class<? extends Erasure> clz = e1.getClass();
	// Get member variable name
	Field[] fields = clz.getDeclaredFields();
	for (Field f : fields) {
		System.out.println(f.getName() + ":" + f.getType().getSimpleName());
	}
	//Print result: key:Object
}

Limited type erasure

Type defined parameters in erase method

@Test
public void testFun5() {
	// Generic type not specified
	Erasure e1 = new Erasure();
	// Obtain Class object of bytecode file of Erasure Class by reflection
	Class<? extends Erasure> clz = e1.getClass();
	// Get all methods
	Method[] methods = clz.getDeclaredMethods();
	for(Method method : methods) {
		System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName());
	}
	/*Print results:
	 
	 getKey:Object
	 setKey:void
	 getValue:Number
	 
	 */
}

Bridging method

@Test
public void testFun6() {
	Class<InfoImpl> infoClass = InfoImpl.class;
	Method[] methods = infoClass.getDeclaredMethods();
	for(Method method : methods ) {
		System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName());
	}
	// info:Integer
	// info:Object
}

(6) Generics and arrays

Creation of generic array

  • You can declare array references with generics, but you cannot directly create array objects with generics
  • You can create an array of T [] through the newinstance (class < T >, int) of java.lang.reflect.Array
  • The function of using generics is to enable the program to detect type related errors at compile time, but if generic arrays are used, this ability will be destroyed.
@Test
public void testFun1() throws Exception {
	/*
	 * Array references with generics can be declared: ArrayList < string > [] ArrayList
	 * But you cannot directly create an array object with generics: new ArrayList < string > [10]; / / error
	 */
	ArrayList<String>[] arrayList = new ArrayList[10];
	arrayList[0] = new ArrayList<String>();
	arrayList[0].add("hello");
	System.out.println(arrayList[0]);	//Output: [hello]
	System.out.println(arrayList[1]);	//Output: null
	/*
 	 * Create Person array: Person[] p = new Person[10];
	 */
	Person<String>[] p = new Person[10];
	p[0] = new Person<String>();
}

@Test
public void testFun2() throws Exception {
	
	/*
	 * You can create an array of 't []' through 'newinstance (class < T >, int)' of 'java.lang.reflect.Array'
	 */
	Person[] p =  (Person[]) Array.newInstance(Person.class, 10);
	System.out.println(p.getClass());// class [Ldemo03.Person; [array type
	
}

(7) Generics and Reflections

Reflecting common generic classes

  • Class
  • Constructor
@Test
public void testFun() throws Exception {
	Person p ;
	Class<Person> c = Person.class;
	Constructor<Person> constructor = c.getConstructor();
	Person person = constructor.newInstance();
	System.out.println(person);
}

Why is it not allowed to create generic arrays directly in Java - reference link: https://blog.csdn.net/x_iya/article/details/79550667

Published 12 original articles · praised 4 · visited 133
Private letter follow

Tags: Java JDK jvm

Posted on Thu, 16 Jan 2020 04:23:59 -0500 by Lustre