Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Learn more about what java generics mean


May 30, 2021 Article blog


Table of contents


Generics

Examples explain why generics are introduced

// 不使用泛型
List list = new ArrayList();
list.add("coding");          // 集合中可以添加不同类型的元素(集合就是这么设计的,主要是为了实现通用性,但也带来了弊端,泛型就是为了解决这个产生的)
list.add(1024);                         // 元素丢进集合中全部变成了Object
String result1 = list.get(0);           // 此行代码编译器不过
String result2 = (String)list.get(0);    // 如果想要还原集合中元素需要使用强制类型转换,强制类型转换可能引发异常,因为集合中元素类型有多种。
String result3 = (String)list.get(1);    // 此行代码运行时会报类型转换异常ClassCastException,所以说集合不使用泛型来限制数据类型的话很容易产生bug
System.out.println(result2);

The definition of a generic

1, through the introduction of the above example, we can conclude: generics are essentially parametric types, we can specify a type parameter for classes, interfaces, methods, through this parameter to limit the operation of the data type, so as to ensure the absolute security of type conversion.

2, basic usage: generic collection

// 使用泛型
List<String> str1 = new ArrayList<String>();     // 在<>中指定集合中元素类型
str1.add("java");
str1.add(1024);            // 此行代码编译器报错,也就是限制了集合中类型只能为String类型,避免了强制类型转化时出现异常

Other uses of generics

  • The example above tells us that generics can address weaknesses in collections, but generics do more than that.

Generic method

  • Generic methods need to add < T > before the method's return type is defined, which can be replaced with another letter, T represents what type of argument the method is, T can represent any wrapper type, and the basic type is not supported.
  • Generic methods do not explicitly specify the data type of their parameters, but do not determine the data type until the method is used. T he benefit is that a generic approach accepts different types of input parameters, reducing duplicate code. The following example is for illustration purposes only.
public class Generics_Test {
	// 泛型方法
	public static <T> void print(T[] arr) {
		System.out.println(arr[0]);
	}
	
	public static void main(String[] args) {
		String[] str2 = {"test"};
		print(str2);
		Integer[] num = {1024};
		print(num);
	}
}

Generic class

  • Introducing background: When there are multiple generic methods in a class, generic classes are introduced in order to avoid the need to add < T> to indicate that they are generic methods when declaring each generic method.
// 泛型类
public class Generics_Test<T> {

	public static <T> void print(T[] arr) {      // static 仍然需要显示声明<T>,否则会报错,因为静态方法不要类实例化就能调用。
		System.out.println(arr[0]);
	}
	
	public void printf(T[] arr) {               // 普通方法不需要再声明<T>
		System.out.println(arr[0]);
	}
	
	public static void main(String[] args) {
	
		Generics_Test<String> gt = new Generics_Test<String>();
		String[] str2 = {"test"};
		gt.printf(str2);
		
		Generics_Test<Integer> gt1 = new Generics_Test<Integer>();
		Integer[] num = {1024};
		gt1.printf(num);
	}
}

Advanced usage of generics

Wildcard: <? >

  • With <?> you can do without specifying a parameter type, i.e. you do not have to declare < T > before the method returns a value
// 通配符<?>
public class Generics_Test {

	public static void print(List<?> arr) {       // 使用 <?> 可以不用指定参数类型,即不用在方法的返回值前声明<T>
		Object result = arr.get(0);
		System.out.println(result);
	}
	
	public static void main(String[] args) {
		List<String> str1 = new ArrayList<String>();
		str1.add("coding");
		print(str1);
	}
}

Wildcard: <? extends anyClass>

  • Java generics default to the possible instantiation of a generic class object using any wrapper type
public class Generics_Test<T extends Object> {  
	public static void main(String[] args) {
		// 因为object是所有类型的父类,所以可以使用任何包装类型来实例化一个泛型类对象
		Generics_Test<ArrayList> arr1 = new Generics_Test<ArrayList>();
		Generics_Test<LinkedList> link1 = new Generics_Test<LinkedList>();
		Generics_Test<HashMap> str1 = new Generics_Test<HashMap>();
	}
}
  • Limit the types available to generic classes. T extends anyClass The generic class accepts a type that must inherit or implement anyClass (where anyClass represents a class or interface)
public class Generics_Test<T extends List> {   
	public static void main(String[] args) {
		Generics_Test<ArrayList> arr1 = new Generics_Test<ArrayList>();
		Generics_Test<LinkedList> link1 = new Generics_Test<LinkedList>();
		Generics_Test<List> list1 = new Generics_Test<List>();      
		Generics_Test<HashMap> hashmap1 = new Generics_Test<HashMap>(); // 此行代码会报错,因为HashMap没有实现List接口
	}
}

Inheritance of generic classes

public class Generics_Test<T1>{
}
class SonGenericsClass<T1,T2,T3> extends Generics_Test<T1>{
}

Recommended good lessons: Java micro-class, java interview basic questions should be informed