The easiest way to understand Java generics is to regard it as a convenient syntax that can save you some operations on Java type casting:
List<Apple> box = ...; Apple apple = box.get(0);
The above code itself has clearly expressed: box is a List with Apple objects. The get method returns an Apple object instance, and this process does not require type conversion. There are no generics, the above code needs to be written like this:
List box = ...; Apple apple = (Apple) box.get(0);
It is obvious that the main benefit of generics is to allow the compiler to retain the type information of the parameters, perform type checks, and perform type conversion operations: the compiler ensures that these type conversions are absolutely correct. Compared to relying on programmers to remember object types and perform type conversions - this will cause failures when the program is run, which is difficult to debug and solve. The compiler can help programmers force a large number of type checks at compile time and find errors.
The composition of generics
The composition of generics leads to the concept of type variables. According to the Java language specification, type variables are a type of unrestricted glyph, which arise from the following situations:
Generic class declaration Generic interface declaration Generic method declaration Generic constructor declaration
Generic classes and interfaces
If there are one or more type variables on a class or interface, it is a generic. Type variables are defined by angle brackets and placed after the class or interface name:
public interface List<T> extends Collection<T> {...}Simply put, the role of type variables is like a parameter, which provides information to the compiler for type checking.
Many classes in the Java class library, such as the entire Collection framework, have been modified in generic form. For example, the List interface we used in the first code above is a generic class. In that code, box is a List<Apple> object, which is an instance of a class implementation of a List interface with an Apple type variable. The compiler uses this type variable parameter to automatically convert the get method when it is called and returns an Apple object.
In fact, this newly emerging generic tag, or the get method in this List interface, is as follows:
T get(int index);
The get method actually returns an object of type T, which is a type variable in the List<T> declaration.
Generic methods and constructors
Very similar, if one or more type variables are declared on the method and constructor, they can also be generic.
public static <t> T getFirst(List<T> list)
This method will accept a List<T> parameter and return an object of type T. You can use the generic classes provided in the Java class library, or you can use your own generic classes. Type-safe writing data... The following code is an example. We create a List<String> instance and then load some data:
List<String> str = new ArrayList<String>(); str.add("Hello "); str.add("World.");If we try to load another object in List<String>, the compiler will prompt an error:
str.add(1);
Type-safe reading data...
When we are using a List<String> object, it always guarantees that we get a String object:
String myString = str.get(0);
Traversal: Many classes in the class library, such as Iterator<T>, have enhanced functions and are genericized. The iterator() method in the List<T> interface now returns Iterator<T>. The object returned by its T next() method does not need to be type-converted, you directly get the correct type.
for (Iterator<String> iter = str.iterator(); iter.hasNext();) {String s = iter.next();System.out.print(s);}With foreach, the "for each" syntax also benefits from generics. The previous code can be written like this:
for (String s: str) {System.out.print(s);}This is easy to read and maintain.
Automatic encapsulation (Autoboxing) and automatic unpacking (Autounboxing). When using Java generics, the two features of autoboxing/autounboxing will be automatically used, just like the following code:
List<Integer> ints = new ArrayList<Integer>(); ints.add(0);ints.add(1); int sum = 0;for (int i : ints) { sum += i; }However, one thing you need to understand is that packaging and unpacking will bring performance losses, and all, general purpose should be used with caution.
Generics are a new feature of Java SE 1.5. The essence of generics is a parameterized type, that is, the data type operated is specified as a parameter. This parameter type can be used in the creation of classes, interfaces and methods, and is called generic classes, generic interfaces, and generic methods respectively.
The advantage of introducing generics in Java language is that they are safe and simple.
Before Java SE 1.5, without generics, the "arbitraryization" of parameters was achieved by referencing the type Object. The disadvantage of "arbitraryization" was that explicit cast type conversion was required, and this conversion required developers to predict the actual parameter type. In case of cast type conversion errors, the compiler may not prompt an error, and an exception will only occur when running, which is a security risk.
The advantage of generics is that they check type safety when compiling, and all casts are automatic and implicit, improving the reuse rate of code.
There are some rules and restrictions in use of generics:
1. The type parameters of generic types can only be class types (including custom classes), not simple types.
2. The same generic type can correspond to multiple versions (because the parameter type is uncertain), and the instances of generic class of different versions are incompatible.
3. There can be multiple type parameters for generics.
4. Generic parameter types can use extends statements, for example. Habitually becoming a "bounded type".
5. The parameter type of a generic type can also be a wildcard type. For example Class classType = Class.forName(java.lang.String);
Generics also have interfaces, methods, etc., with a lot of content, and it takes some effort to understand, master and apply them proficiently. Here are two examples I wrote when I learned about generics (written based on the impression I saw), which can realize the same function. One uses generics and the other does not. Through comparison, you can quickly learn the application of generics. Learn this and basically learn 70% of the content of generics.
Example 1: Generics are used
public class GenT { private T ob; //Define generic member variable public Gen(T ob) {this.ob = ob; } public T getOb() {return ob; } public void setOb(T ob) {this.ob = ob; } public void showTyep() {System.out.println("The actual type of T is: " + ob.getClass().getName()); }}public class GenDemo { public static void main(String[] args){ //Define an Integer version of the generic class Gen Gen intOb=new GenInteger(88); intOb.showTyep(); int i= intOb.getOb(); System.out.println("value= " + i); System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Example 2: No generics are used
public class Gen2 { private Object ob; //Define a general type member public Gen2(Object ob) {this.ob = ob; } public Object getOb() {return ob; } public void setOb(Object ob) {this.ob = ob; } public void showTyep() {System.out.println("The actual type of T is: " + ob.getClass().getName()); }}public class GenDemo2 { public static void main(String[] args) {//Define an Integer version of class Gen2 Gen2 intOb = new Gen2(new Integer(88));intOb.showTyep();int i = (Integer) intOb.getOb();System.out.println("value= " + i);System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ strOb.getOb();System.out.println("value= " + s); }}Running results:
The results of running the demo in the two examples are the same, and the console output is as follows:
The actual type of T is:
java.lang.Integer
value= 88
----------------------------------
The actual type of T is: java.lang.String
value= Hello Gen!
Process finished with exit code 0
If you understand this, you will not be a problem in the future when basic generic applications and code reading.
The above is an example analysis of Java generics. Friends who learn Java generics can refer to it.