Preface Before talking about generics, the blogger wants to talk about the meaning of T, KV E, and? In Java generics. How many Xiaobai students are bothered by these things? It's not clear how many hhhhh.
E - Element (used in a collection because it holds elements) T - Type (Java class) T represents the specified type at the time of the call K - Key V - Value N - Number (value type) ? -java type indicating uncertainty is generally used in general configuration
Emphasize one point: These are just some professional logo functions, not necessarily only it can represent these meanings!!! @[toc]
1. Generic overview
I think you all know that any Object can be stored in a collection. As long as the objects are stored in a collection, they will be promoted to Object type. When we are taking out every Object and doing the corresponding operation, we must adopt the type conversion.
Look at the following code:
public class GenericDemo { public static void main(String[] args) { Collection coll = new ArrayList(); coll.add("abc"); coll.add("ADC"); coll.add(5);//Since the collection has no restrictions, any type can be stored in it Iterator it = coll.iterator(); while(it.hasNext()){ //To print the length of each String, you need to convert the iterated object to String type String str = (String) it.next(); System.out.println(str.length()); } } }
The program encountered a problem at run time java.lang.ClassCastException Why do type conversion exceptions occur Let's analyze: because any type of element in the Collection can be stored. Causes a strong transition on fetch to raise a runtime ClassCastException How to solve this problem? Although Collection can store various objects, in fact, Collection usually only stores objects of the same type. For example, they are all storage string objects. Therefore, after JDK5, generic syntax has been added, which allows you to specify classes or methods to support generics when designing API. In this way, when we use API, it becomes more concise and gets syntax check at compile time.
- Generics: unknown types can be used in advance in a class or method.
In general, when creating an Object, the unknown type determines the specific type. When no generics are specified, the default type is Object.
2. Benefits of using generics
The previous section only explained the introduction of generics, so what are the benefits of generics?
1. Transfer the ClassCastException in the runtime to the compilation time and it becomes compilation failure. 2. Avoid the trouble of type forced conversion.
Let's experience the following code:
public class GenericDemo2 { public static void main(String[] args) { Collection<String> list = new ArrayList<String>(); list.add("abc"); list.add("ADC"); // list.add(5); / / when the set has a clear type, the storage type is inconsistent, and an error will be reported // The collection has specified the type of element to store, so when using the iterator, the iterator will also know the type of traversal element Iterator<String> it = list.iterator(); while(it.hasNext()){ String str = it.next(); //When you use iterator < String > to control the element type, you don't need to force conversion. The obtained element is the String type directly System.out.println(str.length()); } } }
Generics are part of data types. We consider class names and generics merging as data types.
3. Definition and use of generics
We will use generics in a large number of collections. Here we will learn generics completely.
Generics are used to flexibly apply data types to different classes, methods and interfaces. Pass the data type as a parameter.
3.1 define and use classes with generics
Definition format:
Modifier class class name < variable representing generic > {}
For example, the ArrayList collection in the API:
class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } .... }
Use generics: when to determine generics.
Determine generics when creating objects
For example, ArrayList < string > List = new ArrayList < string > ();
At this point, the value of variable E is String type, so our type can be understood as:
class ArrayList<String>{ public boolean add(String e){ } public String get(int index){ } ... }
For example, ArrayList < integer > List = new ArrayList < integer > ();
At this point, the value of variable E is of type Integer, so our type can be understood as:
class ArrayList<Integer> { public boolean add(Integer e) { } public Integer get(int index) { } ... }
Example custom generic class
public class MyGenericClass<MVP> { //There is no MVP type, which represents an unknown data type. What type will be passed in the future private MVP mvp; public void setMVP(MVP mvp) { this.mvp = mvp; } public MVP getMVP() { return mvp; } }
Use:
public class GenericClassDemo { public static void main(String[] args) { // Create a class with a generic type of String MyGenericClass<String> my = new MyGenericClass<String>(); // Call setMVP my.setMVP("Little fat Lingling"); // Call getMVP String mvp = my.getMVP(); System.out.println(mvp); //Create a class whose generics are Integer MyGenericClass<Integer> my2 = new MyGenericClass<Integer>(); my2.setMVP(123); Integer mvp2 = my2.getMVP(); } }
3.2 methods with generics
Definition format:
Modifier < variable representing generic > return value type method name (parameter) {}
For example,
public class MyGenericMethod { public <MVP> void show(MVP mvp) { System.out.println(mvp.getClass()); } public <MVP> MVP show2(MVP mvp) { return mvp; } }
Use format: determines the type of generics when calling methods
public class GenericMethodDemo { public static void main(String[] args) { // create object MyGenericMethod mm = new MyGenericMethod(); // Tips for demonstration mm.show("aaa"); mm.show(123); mm.show(12.45); } }
3. 3 interfaces with generics
Definition format:
Modifier interface interface name < variable representing generic > {}
For example,
public interface MyGenericInterface<E>{ public abstract void add(E e); public abstract E getE(); }
Use format:
1. Determine the type of generics when defining classes
for example
public class MyImp1 implements MyGenericInterface<String> { [@Override](https://my.oschina.net/u/1162528) public void add(String e) { // Omission... } [@Override](https://my.oschina.net/u/1162528) public String getE() { return null; } }
At this point, the value of generic E is of type String.
2. The type of generics is not determined until the object is created
for example
public class MyImp2<E> implements MyGenericInterface<E> { [@Override](https://my.oschina.net/u/1162528) public void add(E e) { // Omission... } [@Override](https://my.oschina.net/u/1162528) public E getE() { return null; } }
Determine generics:
/* * Use */ public class GenericInterface { public static void main(String[] args) { MyImp2<String> my = new MyImp2<String>(); my.add("aa"); } }
4. Generic wildcard
When a generic class or interface is used, the generic type in the data passed is uncertain and can be represented by the wildcard character <? >. However, once the generic wildcard is used, only the common methods in the Object class can be used, and the element's own methods in the collection cannot be used.
4.1 basic use of wildcards
Generic wildcard: when you don't know what type to use to receive, you can use?,? To indicate unknown wildcard.
At this time, data can only be accepted and cannot be stored in the collection.
For example, you can understand and use:
public static void main(String[] args) { Collection<Intger> list1 = new ArrayList<Integer>(); getElement(list1); Collection<String> list2 = new ArrayList<String>(); getElement(list2); } public static void getElement(Collection<?> coll){} //? Delegate can receive any type
There is no inheritance relationship for generics collection < Object > List = new ArrayList < string > (); this is wrong.
4.2 advanced use of wildcard -- restricted generics
When you set generics before, you can actually set them at will, as long as they are classes. However, in JAVA generics, you can specify an upper and lower limit of generics.
Upper limit of generics:
- Format: type name <? Extends class > object name
- Meaning: only this type and its subclasses can be received
Lower bound of generics:
- Format: type name <? Super class > object name
- Meaning: only this type and its parent type can be received
For example, now we know the Object class, String class, Number class and Integer class, where Number is the parent class of Integer
public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<Integer>(); Collection<String> list2 = new ArrayList<String>(); Collection<Number> list3 = new ArrayList<Number>(); Collection<Object> list4 = new ArrayList<Object>(); getElement(list1); getElement(list2);//Report errors getElement(list3); getElement(list4);//Report errors getElement2(list1);//Report errors getElement2(list2);//Report errors getElement2(list3); getElement2(list4); } // Upper limit of generics: at this time, generics? Must be subclasses of type Number or Number public static void getElement(Collection<? extends Number> coll){} // Lower limit of generics: the generics? At this time must be the parent class of Number type or Number type public static void getElement2(Collection<? super Number> coll){}
So far, the basic use of generics is almost the same. Of course, if you want to know more about generics, you can refer to
java generic explanation - absolutely the most detailed explanation of generic methods, no one
Recommend reading the next two java articles in this column
[java foundation] java inheritance starts from "my father is Li Gang"