Java Generics (Generic) Overview and use

Introduction:

See the following demo code test

package cn.wen;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo1 {
	public static void main(String[] args) {
		// 创建
		ArrayList array = new ArrayList();

		// 添加元素
		array.add("hello");
		array.add("world");
		array.add("java");
		//array.add(new Integer(100));
		array.add(10); // JDK5以后的自动装箱
		// 等价于:array.add(Integer.valueOf(10));

		// 遍历
		Iterator it = array.iterator();
		while (it.hasNext()) {
			// ClassCastException
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}

 Output exception:

hello
world
java
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
	at cn.wen.GenericDemo1.main(GenericDemo1.java:49)

 ArrayList to store string and ergodic 
we follow the normal wording to write this program, the result is indeed wrong. Why? Because when we started the stored data is stored two types of String and Integer. And when traversal, we put them all as String type of treatment, do a conversion, so the error.
However, it did not tell us during compilation. So, I felt bad this design.
Recall that we array
         String [] = strArray new new String [. 3];
        strArray [0] = "Hello";
        strArray [. 1] = "World";
         strArray [2] = 10;

Collection also imitate the practice of the array, clear data type elements (strings) when you create the object. This will not be a problem.
And this technique is called: generics.
 
Generics : a definite type of work to be postponed until the time to create an object or method call before going to express a special type. Parameterized type, the same type as a parameter passed.
Format:
        <data type>
        data type here can only be a reference type.
 Benefits:
         A: The problem is running ahead of time to compile
         B: to avoid the cast
         C: optimized programming to solve the yellow warning line
 

Java Generics

Java generics (generics) is a new feature introduced in JDK 5, generics provide compile-time type safety detection mechanism, this mechanism allows programmers to detect illegal type at compile time. Generic nature of the parameter type, data type that is being operated is specified as a parameter.

Suppose we have such a demand: to write a sorting method, able to array of integers, strings, arrays or even any other type of array to sort, how to achieve? The answer is that you can use  Java generics . Use Java Generics, we can write a generic method to sort an array of objects. Then, call the generic method to sort the array of integers, floating point arrays, an array of strings and the like.

Modifying the above code: normal output

package cn.wen;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo1 {
	public static void main(String[] args) {
		// 创建
		ArrayList<String> array = new ArrayList<String>();

		// 添加元素
		array.add("hello");
		array.add("world");
		array.add("java");
		//array.add(new Integer(100));
		//array.add(10); // JDK5以后的自动装箱
		// 等价于:array.add(Integer.valueOf(10));

		// 遍历
		Iterator<String> it = array.iterator();
		while (it.hasNext()) {
			// ClassCastException
			//String s = (String) it.next();  //改进如下
			String s = it.next();
			System.out.println(s);
		}
	}
}

 Generics in what place?
         See API, if with classes, interfaces, abstract class has behind <E> said to be the use of generics. In general it is used in the collection.

Case:

1), with the string ArrayList storage element, and traverse. Improvement with Generic Code

package cn.wen_02;

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListDemo {
	public static void main(String[] args) {
		// 用ArrayList存储字符串元素,并遍历。用泛型改进代码
		ArrayList<String> array = new ArrayList<String>();

		array.add("hello");
		array.add("world");
		array.add("java");

		Iterator<String> it = array.iterator();
		while (it.hasNext()) {
			String s = it.next();
			System.out.println(s);
		}
		System.out.println("-----------------");

		for (int x = 0; x < array.size(); x++) {
			String s = array.get(x);
			System.out.println(s);
		}
	}
}

2) Demand: store custom objects and traversal.
  
 A: Create Student Class
 B: Create collection object
 C: Create element object
 D: adding an element to the set
 E: through the collection
 

package cn.wen_02;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * 需求:存储自定义对象并遍历。
 * 
 * A:创建学生类
 * B:创建集合对象
 * C:创建元素对象
 * D:把元素添加到集合
 * E:遍历集合
 */
public class ArrayListDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		// JDK7的新特性:泛型推断。
		// ArrayList<Student> array = new ArrayList<>();
		// 但是我不建议这样使用。
		ArrayList<Student> array = new ArrayList<Student>();

		// 创建元素对象
		Student s1 = new Student("小明", 40); 
		Student s2 = new Student("小东", 30); 
		Student s3 = new Student("小亮", 26);

		// 添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);

		// 遍历
		Iterator<Student> it = array.iterator();
		while (it.hasNext()) {
			Student s = it.next();
			System.out.println(s.getName() + "---" + s.getAge());
		}
		System.out.println("------------------");

		for (int x = 0; x < array.size(); x++) {
			Student s = array.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

Student categories:

package cn.wen_02;

public class Student {
	// 姓名
	private String name;
	// 年龄
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

Generic Origin

Why do generics ?
  • Introduced by Case
  • Early Object types may receive any type of object, but in actual use, there is a problem type conversion. This risk also exists, so Java provides a generic to solve this security problem.

Generic applications

Generic class
The generic class defined in the
Format : public class name of the class < generic type 1, ...>
Note : generic type must be a reference type
Pan- type method
The generic method defined in
Format : public < generic type > return type name ( generic type .)
Pan Interface
The generic definition interface
Format : public interface interface name < generic type 1 ...>

 

1, a generic class

And non-generic type declarations statements generic class is similar, except that after the class name in the added parameter type declaration section.

And generic methods as part of a generic class type parameter declaration may also contain one or more types of parameters, the parameters are separated by commas. A generic parameter, also referred to as a variable type is used to specify the name of a generic type identifier. Because they accept one or more parameters, these classes are called parameterized classes or parameterized type.

Generic class:

package cn.wen_04;

/*
 * 泛型类:把泛型定义在类上
 */
public class ObjectTool<T> {
	private T obj;

	public T getObj() {
		return obj;
	}

	public void setObj(T obj) {
		this.obj = obj;
	}
}

Test category

package cn.wen_04;

/*
 * 泛型类的测试
 */
public class ObjectToolDemo {
	public static void main(String[] args) {
		// ObjectTool ot = new ObjectTool();
		//
		// ot.setObj(new String("风清扬"));
		// String s = (String) ot.getObj();
		// System.out.println("姓名是:" + s);
		//
		// ot.setObj(new Integer(30));
		// Integer i = (Integer) ot.getObj();
		// System.out.println("年龄是:" + i);

		// ot.setObj(new String("林青霞"));
		// // ClassCastException
		// Integer ii = (Integer) ot.getObj();
		// System.out.println("姓名是:" + ii);

		System.out.println("-------------");

		ObjectTool<String> ot = new ObjectTool<String>();
		// ot.setObj(new Integer(27)); //这个时候编译期间就过不去
		ot.setObj(new String("林青霞"));
		String s = ot.getObj();
		System.out.println("姓名是:" + s);

		ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		// ot2.setObj(new String("风清扬"));//这个时候编译期间就过不去
		ot2.setObj(new Integer(27));
		Integer i = ot2.getObj();
		System.out.println("年龄是:" + i);
	}
}

Examples

The following examples demonstrate how we define a generic class:

public class Box<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
 
    integerBox.add(new Integer(10));
    stringBox.add(new String("HolleWorld"));
 
    System.out.printf("整型值为 :%d\n\n", integerBox.get());
    System.out.printf("字符串为 :%s\n", stringBox.get());
  }
}

2, the pan type process

You can write a generic method that can receive different types of parameters when calling. The parameters passed to the method of the generic type, the compiler properly processed each method call.

The following is a generic method definition of rules:

  • All statements have a generic method type parameter declaration section (delimited by angle brackets), the parameter type declaration section before the method return type (in the following example of <E>).
  • Each type parameter declaration section comprises one or more types of parameters, the parameters are separated by commas. A generic parameter, also referred to as a variable type is used to specify the name of a generic type identifier.
  • Parameters can be used to declare the type of the return type, argument types, and can be used as placeholders for actual generic method obtained.
  • Declare a generic method and other methods, like body. Note that type parameter type can only represent a reference type, can not be a primitive type (like int, double, char, etc.).

Generic method class:

package cn.itcast_05;

//未使用泛型之前
//public class ObjectTool<T> {
//	// public void show(String s) {
//	// System.out.println(s);
//	// }
//	//
//	// public void show(Integer i) {
//	// System.out.println(i);
//	// }
//	//
//	// public void show(Boolean b) {
//	// System.out.println(b);
//	// }
//
//	public void show(T t) {
//		System.out.println(t);
//	}
// }

/*
 * 泛型方法:把泛型定义在方法上
 */
public class ObjectTool {
	public <T> void show(T t) {
		System.out.println(t);
	}
}

 Test generic method class:

package cn.wen_05;

public class ObjectToolDemo {
	public static void main(String[] args) {
		// ObjectTool ot = new ObjectTool();
		// ot.show("hello");
		// ot.show(100);
		// ot.show(true);

		// ObjectTool<String> ot = new ObjectTool<String>();
		// ot.show("hello");
		//
		// ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		// ot2.show(100);
		//
		// ObjectTool<Boolean> ot3 = new ObjectTool<Boolean>();
		// ot3.show(true);

		// 说明泛型类是没有问题的
		// 但是呢,谁说了我的方法一定要和类的类型的一致呢?
		// 要是类上没有泛型的话,方法还能不能接收任意类型的参数了呢?

		// 定义泛型方法后
		ObjectTool ot = new ObjectTool();
		ot.show("hello");
		ot.show(100);
		ot.show(true);
	}
}

Examples

The following example demonstrates the "extends" How to use the means in a general sense "extends" (class) or "implements" (Interface). Generic methods in this example returns the maximum of three comparable objects.

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}
3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

3, generic interface

 Interface type:

package cn.wen_06;

/*
 * 泛型接口:把泛型定义在接口上
 */
public interface Inter<T> {
	public abstract void show(T t);
}

Implementing Classes: 

package cn.wen_06;

//实现类在实现接口的时候
//第一种情况:已经知道该是什么类型的了

//public class InterImpl implements Inter<String> {
//
//	@Override
//	public void show(String t) {
//		System.out.println(t);
//	}
// }

//第二种情况:还不知道是什么类型的
public class InterImpl<T> implements Inter<T> {

	@Override
	public void show(T t) {
		System.out.println(t);
	}
}

Test categories:

package cn.wen_06;

public class InterDemo {
	public static void main(String[] args) {
		// 第一种情况的测试
		// Inter<String> i = new InterImpl();
		// i.show("hello");

		// // 第二种情况的测试
		Inter<String> i = new InterImpl<String>();
		i.show("hello");

		Inter<Integer> ii = new InterImpl<Integer>();
		ii.show(100);
	}
}

 

Senior generic (wildcard)

  • Generic wildcard <?>
Any type, if not explicitly, then that Object as well as any Java class of
  • ? extends E
Defining downwardly, E and its subclasses
  • ? overcome
Upwardly defined, E and its parent

 

package cn.wen;

import java.util.ArrayList;
import java.util.Collection;

/*
 * 泛型高级(通配符)
 * ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
 * ? extends E:向下限定,E及其子类
 * ? super E:向上限定,E极其父类
 */
public class GenericDemo {
	public static void main(String[] args) {
		// 泛型如果明确的写的时候,前后必须一致
		Collection<Object> c1 = new ArrayList<Object>();
		// Collection<Object> c2 = new ArrayList<Animal>();
		// Collection<Object> c3 = new ArrayList<Dog>();
		// Collection<Object> c4 = new ArrayList<Cat>();

		// ?表示任意的类型都是可以的
		Collection<?> c5 = new ArrayList<Object>();
		Collection<?> c6 = new ArrayList<Animal>();
		Collection<?> c7 = new ArrayList<Dog>();
		Collection<?> c8 = new ArrayList<Cat>();

		// ? extends E:向下限定,E及其子类
		// Collection<? extends Animal> c9 = new ArrayList<Object>();//报错
		Collection<? extends Animal> c10 = new ArrayList<Animal>();
		Collection<? extends Animal> c11 = new ArrayList<Dog>();
		Collection<? extends Animal> c12 = new ArrayList<Cat>();

		// ? super E:向上限定,E极其父类
		Collection<? super Animal> c13 = new ArrayList<Object>();
		Collection<? super Animal> c14 = new ArrayList<Animal>();
		// Collection<? super Animal> c15 = new ArrayList<Dog>();
		// Collection<? super Animal> c16 = new ArrayList<Cat>();
	}
}

class Animal {
}

class Dog extends Animal {
}

class Cat extends Animal {
}

 

                                                                                                                                                                              --- Come on!

Published 91 original articles · won praise 16 · views 1174

Guess you like

Origin blog.csdn.net/hewenqing1/article/details/103904301