Java generic, java generic
Introduction
Generic refers to the ability of parameterized types. You can define classes, interfaces, or methods of generic types. Then, the compiler replaces them with specific types.
The main advantage of using generics is that errors can be detected during compilation rather than during runtime.
Package java. lang; public interface Comparable {// before JDK1.5 public int compareTo (Object o);} package java. lang; public interface Comparable <T >{// public int compareTo (T o) after JDK1.5 );}
Possible errors detected during compilation of the new generic type:
Comparable c = new Date();System.out.println(c.compareTo("red"));Comparable<Date> c = new Date();System.out.println(c.compareTo("red"));
The generic type must be a reference type and cannot be replaced by a basic type such as int, double, or char:
ArrayList<int> intlist = new ArrayList<int>(); //error
Required:
ArrayList<Integer> intList = new ArrayList<Integer>();
Java will automatically package:
ArrayList <Integer> intList = new ArrayList <Integer> (); intList. add (5); // java automatically Packs 5 as new Integer (5)
Define generic classes and interfaces
The following is an example of a generic class:
Public class GenericStack <E> {ArrayList <E> list = new ArrayList <E> (); public int getSize () {return list. size ();} public E peek () {return list. get (getSize ()-1);} public void push (E o) {list. add (o);} public E pop () {E o = list. get (getSize ()-1); list. remove (getSize ()-1); return o;} public boolean isEmpty () {return list. isEmpty ();}}View Code
Add elements to the stack:
GenericStack<String> stack1 = new GenericStack<String>();stack1.push("London");stack1.push("Paris");stack1.push("Berlin");GenericStack<Integer> stack2 = new GenericStack<Integer>();stack2.push(1);stack2.push(2);stack2.push(3);Define generic methods
public static void main(String args[]){ Integer[] integers = {1, 2, 3, 4, 5}; String[] strings = {"London", "Paris", "New York", "Austin"}; print(integers); print(strings);} public static <E> void print(E[] list) { for(int i = 0; i < list.length; i++) System.out.print(list[i] + " "); System.out.println();}Wildcard
The following example shows why generic wildcard is used:
public class Main{ public static void main(String args[]) { GenericStack<Integer> intStack = new GenericStack<Integer>(); intStack.push(1); intStack.push(2); intStack.push(-2); System.out.print("The max number is " + max(intStack)); } public static double max(GenericStack<Number> stack) { double max = stack.pop().doubleValue(); while(!stack.isEmpty()) { double value = stack.pop().doubleValue(); if(value > max) max = value; } return max; } }
A compilation error occurs when a row is marked. intStack is not an instance of GenericStack <Number>. Although Integer is a child type of Number, GenericStack <Integer> is not a child type of GenericStack <Number>, to avoid this problem, wildcard types can be used. wildcard types have three forms:
Unrestricted wildcard :? (It and? Extends Object is the same)
Restricted wildcard :? Extends T (an unknown child type of T or T)
Minimum wildcard :? Super T (an unknown parent type of T or T)
The code after the restricted configuration is modified is as follows:
public class Main{ public static void main(String args[]) { GenericStack<Integer> intStack = new GenericStack<Integer>(); intStack.push(1); intStack.push(2); intStack.push(-2); System.out.print("The max number is " + max(intStack)); } public static double max(GenericStack<? extends Number> stack) { double max = stack.pop().doubleValue(); while(!stack.isEmpty()) { double value = stack.pop().doubleValue(); if(value > max) max = value; } return max; } }
Let's look at the following example:
public class Main{ public static void main(String args[]) { GenericStack<Integer> intStack = new GenericStack<Integer>(); intStack.push(1); intStack.push(2); intStack.push(-2); print(intStack); } public static void print(GenericStack<?> stack) { while(!stack.isEmpty()) { System.out.print(stack.pop() + " "); } } }
When can I use a lower limit? See the following example:
public class Main{ public static void main(String args[]) { GenericStack<String> stack1 = new GenericStack<String>(); GenericStack<Object> stack2 = new GenericStack<Object>(); stack2.push("Java"); stack2.push(2); stack1.push("Sun"); add(stack1, stack2); print(stack2); } public static<T> void add(GenericStack<T> stack1, GenericStack<? super T> stack2) { while(!stack1.isEmpty()) { stack2.push(stack1.pop()); } } public static void print(GenericStack<?> stack) { while(!stack.isEmpty()) { System.out.print(stack.pop() + " "); } } }Eliminate generics and restrictions on Generics
Generics are implemented by a method called type elimination. Generic information is unavailable at runtime. This method can make the generic code backward compatible with legacy code of the original type.
Generics exist at compilation. Once the compiler confirms that the generic type is safe to use, it is converted to the original type.
For example, the following code:
ArrayList<String> list = new ArrayList<String>();list.add("Oklahoma");String state = list.get(0);
The original type of the Code translated as follows:
ArrayList list = new ArrayList();list.add("Oklahoma");String state = (String)list.get(0);
There are some restrictions on the use of generic types:
Limit 1: new E () cannot be used ()
You cannot use generic parameters to create instances: E object = new E ()
Limit 2: new E () cannot be used ()
You cannot use generic parameters to create arrays, for example, E [] elements = new E [capacity].
You can avoid this restriction by creating an array of the Object type and converting its type to E [], for example, E [] elements = (E []). new Object [capacity];
Limit 3: Class parameters are not allowed to be generic in a static Environment
Because all instances of a generic class have the same runtime class, the static variables and methods of the generic class are shared by all its instances. The following code is invalid:
public calss Test<E> { public static Void m(E o1) { } public static E o1; static { E o2; }}
Limit 4: exception classes cannot be generic
How to use Java generics?
Public class Test <T> {
Private T name;
Public T getName (){
Return name;
}
Public void setName (T name ){
This. name = name;
}
Public static void main (String [] args ){
Test <String> stringTest = new Test <String> ();
StringTest. setName ("aaa ");
System. out. println (stringTest. getName ());
Test <Integer> integerTest = new Test <Integer> ();
IntegerTest. setName (1111 );
System. out. println (integerTest. getName ());
}
}
How to use Java generics?
Public class Test <T> {
Private T name;
Public T getName (){
Return name;
}
Public void setName (T name ){
This. name = name;
}
Public static void main (String [] args ){
Test <String> stringTest = new Test <String> ();
StringTest. setName ("aaa ");
System. out. println (stringTest. getName ());
Test <Integer> integerTest = new Test <Integer> ();
IntegerTest. setName (1111 );
System. out. println (integerTest. getName ());
}
}