Java generics in-depth explanation

Source: Internet
Author: User
Tags true true java se

1. What is Java generics?

generics are Java SE 1.5 new feature, the nature of generics is a parameterized type, meaning that the data type being manipulated is specified as a parameter. This type of parameter can be used in the creation of classes, interfaces, and methods, called generic classes, generic interfaces, and generic methods, respectively.

2. Why do I need generics?

Java the benefits of introducing generics are safe and simple. You can advance a run-time error to a compile-time error .

in the Java SE 1.5 before, there is no generic case for the under, by-type Object to implement the parameter's reference . " free of " , " free of " The disadvantage is to do explicit coercion of type conversions, which require developers to be able to predict the actual parameter types. In the case of coercion of type conversion errors, the compiler may not prompt for an error and an exception occurs at run time, which is a security risk. the benefit of generics is that it checks for type safety at compile time, and all casts are automatic and implicit, increasing the rate of reuse of the code.

The sample code is as follows:

Package Generics;class Simplegen {Private Object Ob;public Simplegen (Object ob) {this.ob = OB;} Public Object Getob () {return OB;} public void Setob (Object ob) {this.ob = OB;} public void ShowType () {System.out.println (Ob.getclass (). GetName ());}} public class SimpleGenDemo1 {public static void main (string[] args) {Simplegen sg = new Simplegen (new Integer); Type (); int i = (Integer) Sg.getob (); Forced type conversion, the system may throw a ClassCastException exception message System.out.println ("value =" + i); Simplegen SG2 = new Simplegen ("Palm Hongseong"); Sg2.showtype ();               Coercion type conversion, the system may throw a classcastexception exception message String str = (string) Sg2.getob (); System.out.println ("value =" + str);}} /* The output is: Java.lang.Integervalue = 99java.lang.stringvalue = Handheld Hongseong */

3, what is the tuple class library, how to use? 3.1. Why are tuple tuples used?

Tuples, like list lists, can be used for data storage, including multiple data, but unlike lists: Lists can only store the same data type, and tuples are different, and they can store various data types, such as storing int, string, list, etc. at the same time, and can be infinitely expanded as required.

For example, in Web applications, often encounter a problem is the data paging problem, query paging needs to include several information: the current page, page size, query results return data is: the current pages of data records, but if you need to display the current page, page size, total number of pages and other information in the foreground, There must be another message: The total number of data records, and then based on the above information to calculate the total pages and other information. This time to query a page of information needs to return two data types, one is the list (the current data record), one is an int (total number of records). Of course, these two values can be obtained entirely in two methods and two database connections. In fact, when querying the list, has been through the SQL query total record number, if you open a method, then do a database connection to query the total record number, unavoidably a bit superfluous, wasting time, wasting code, wasting life. Strongly worded ~ In this case, we can use the two-tuple, in a database connection, to get the total record, the current page records, and stored in it, simple and clear!

3.2. code example
package Generics;import;class twotuple<a,b>{public Final a first;public final B second;public TwoTuple (a A, b b) {//Here is the parenthesis, not the bracket first = A;second = b;} Public String toString () {return "(" + First + "," + Second + ")";}} Class Threetuple<a,b,c> extends Twotuple<a,b>{private final C three;public threetuple (A, A, B,c c) {super (A, b ); three = C;} Public String toString () {return "(" + First + "," + Second + "," + Three + ")";}} public class Tupletest {public static void main (string[] args) {twotuple<integer,string> twot = new Twotuple<inte Ger,string> (99, "Palm Hongseong"); System.out.println (TWOT); System.out.println ("====== Extended tuple class library after ======"); threetuple<integer,string,date> threet= New threetuple<integer,string,date> (99, "Palm Hongseong", New Date ()); System.out.println (Threet);}} /* Output: * (99, handheld Hongseong) ====== extended tuple class library after ====== (99, Palm Hongseong, Thu Apr 17:59:30 CST) * */

4, how to customize the generic interface, generic class? 4.1 Java generic interface, generic class introduction

The type parameters in a generic class can be used almost anywhere that the interface name, class name can be used, and the following code example shows part of the definition of the Map interface in the collection framework in JDK 5.0:

Public interface Map<k, v> {

public void put (K key, V value);

Public V get (K key);


When declaring or instantiating a generic object, you must specify the value of the type parameter:

map<string, string> map = newhashmap<string, string> ();

For common generic patterns, the recommended name is:

The k--key, such as the mapped key.

v--values, such as the contents of list and Set, or the values in a Map.

e--Exception class.

t--generic type.

Generics are not covariant

A common source of confusion about generics is to assume that they are covariant like arrays. In fact, they are not co-variable. List<object> is not a parent type of list<string>.

If a expands B, then the array of a is also an array of B, and can be used completely where b[] is needed a[]:

integer[] Intarray = new INTEGER[10];

number[] Numberarray = Intarray;

The above code is valid because an integer is a number, and an integer array is an array of number. But not for generics. The following code is not valid:

list<integer> intlist = newarraylist<integer> ();

list<number> numberlist = intlist; Invalid

Initially, most Java programmers find this lack of covariance annoying, or even "bad", but there is a good reason for this broken. If you can assign list<integer> to List<number>, the following code violates the type-safety that generics should provide:

list<integer> intlist = newarraylist<integer> ();

list<number> numberlist = intlist; Invalid

Numberlist.add (New Float (3.1415));

Because Intlist and numberlist are both aliases, if allowed, the above code will let you put things that are not integers into the intlist.

4.2 Code Examples
Package Generics;import java.util.random;interface generator<t> {public T next ();} Class Coffee{public String toString () {return getclass (). Getsimplename ();}}  Class Mocha extends Coffee{}class Cappuccino extends Coffee{}class breve extends Coffee{}class Latte extends Coffee{}class Coffeegenerator implements generator<coffee>{//t for coffeeprivate static random rand = new Random (;p rivate class[ ] types = {Latte.class, mocha.class, Cappuccino.class, breve.class};p ublic Coffee next () {//t = coffeetry {return (Coffee) t Ypes[rand.nextint (Types.length)].newinstance ();} catch (Exception e) {throw new RuntimeException (e);}}}  public class Interfacegentest {public static void main (string[] args) {Coffeegenerator Gen = new Coffeegenerator (); for (int i=0; i<4; i++) {System.out.println ( ());}}} /*cappuccinomochacappuccinolatte*/
5 How to customize a generic method. 5.1 Generic methods

A generic method allows the method to change independently of the class. Here's a basic guideline: whenever you can do it, you should try to use a generic method. That is, if you use a generic method to replace the entire class with generics, you should only use a generic method, because it can make things clearer. In addition, the type parameters of a generic class cannot be accessed for a static method. Therefore, if the static method requires the use of generic capabilities, it must be made a generic method.

To define a generic method, simply place the generic parameter list before the return value , as follows:

5.2 Code Examples
Package Generics;public class Genericmethods {//When the reference data type of the method operation is undefined, you can define the generic on the method public <T> void F (T x) { System.out.println (X.getclass (). GetName ());} public static void Main (string[] args) {genericmethods gm = new Genericmethods (); Gm.f (a); GM.F ("Pocket Hongseong"); Gm.f (New Integer ( GM.F (18.88); GM.F (' a '); Gm.f (GM);}}  /* Output Result: java.lang.Integerjava.lang.Stringjava.lang.Integerjava.lang.Doublejava.lang.CharacterGenerics.GenericMethods */

5.3 Variable parameters and generic methods

A generic method can coexist well with a mutable parameter list:

Package Generics;import Java.util.arraylist;import Java.util.list;public class Genericvarargs {public static <T> List<t> makeList (t ... args) {list<t> result = new arraylist<t> (); for (T Item:args) result.add (item); return result; }public static void Main (string[] args) {List ls = makeList ("A"); SYSTEM.OUT.PRINTLN (ls); ls = makeList ("A", "B", "C"); SYSTEM.OUT.PRINTLN (ls), ls = makeList ("abcdefghijklmnopqrstuvwxyz". Split ("")); SYSTEM.OUT.PRINTLN (LS);}} /*[a][a, B, C][a, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, z]*/

Generics on static methods: Static methods cannot access generics defined on a class. If the reference data type of a static method operation is undefined, you must define the generic on the method.

Public static<q> void function (Q t) {

System.out.println ("function:" +t);


6, how to build a complex model such as a list of tuples?

An important benefit of generics is the ability to create complex models in a simple and secure manner. such as a list tuple.

Package Generics;import java.util.arraylist;class threetuple2<a,b,c>{public final A first;public final B second; Private final C three;public ThreeTuple2 (A, b b,c C) {first = A;second = B;three = C;} Public String toString () {return "(" + First + "," + Second + "," + Three + ")";}} public class Tuplelist<a,b,c> extends arraylist<threetuple2<a,b,c>> {static Threetuple2<integer ,string,character> h () {return new threetuple2<integer,string,character> (99, "Pocket Hongseong", ' A ');} public static void Main (string[] args) {tuplelist<integer,string,character> ts = new tuplelist<integer,string, Character> (); Ts.add (H ()); Ts.add (H ()); for (threetuple2<integer,string,character> Ttp:ts) SYSTEM.OUT.PRINTLN (TTP);}} Package Generics;import java.util.arraylist;class threetuple2<a,b,c>{public final A first;public final B second; Private final C three;public ThreeTuple2 (A, b b,c C) {first = A;second = B;three = C;} Public String toString () {return ' ("+ First +", "+ second + "," + Three + ")";}} public class Tuplelist<a,b,c> extends arraylist<threetuple2<a,b,c>> {static Threetuple2<integer ,string,character> h () {return new threetuple2<integer,string,character> (99, "Pocket Hongseong", ' A ');} public static void Main (string[] args) {tuplelist<integer,string,character> ts = new tuplelist<integer,string, Character> (); Ts.add (H ()); Ts.add (H ()); for (threetuple2<integer,string,character> Ttp:ts) SYSTEM.OUT.PRINTLN (TTP);}} /* Output: (99, Pocket Hongseong, a) (99, Pocket Hongseong, a) */

7, the generic Erase 7.1 code example:
Package Generics;import java.util.*;p ublic class Erasedtypeequivalence {public static void main (string[] args) {Class C1 = New Arraylist<string> (). GetClass (); Class C2 = new arraylist<integer> (). GetClass (); SYSTEM.OUT.PRINTLN (C1 = = C2);}} /* * Output:true *///: ~

Within a generic type, you cannot get any information about the type of the generic parameter.

Arraylist<string> and arraylist<integer> are the same type.

7.2 Compensation for Erase

To use a type in an expression, you need to pass the class object of the type explicitly.

Package Generics;class Building {}class House extends Building {}public class classtypecapture<t> {class<t> K Ind;public classtypecapture (class<t> kind) {this.kind = kind;} public boolean F (Object Arg) {return kind.isinstance (ARG);} public static void Main (string[] args) {classtypecapture<building> ctt1 = new Classtypecapture<building> ( Building.class); System.out.println (CTT1.F (New Building ())); System.out.println (CTT1.F (New House ())); classtypecapture

8. Can I create a generic array? How to handle the corresponding application scenario?

As you can see in the following example, you cannot create a generic array. The general solution is to use ArrayList in any place where you want to create a generic array:

Package Generics;public class Erased<t> {private final int SIZE = 100;public static void f (Object arg) {if (Arg inst Anceof t) {}//cannot make a static reference to the non-static type TT var = new T (); errort[] array = new T[size]; errort[] Array = (T) new object[size]; Unchecked Warning}}///: ~

Using the ArrayList sample

Package Generics;import java.util.*;p ublic class Listofgenerics<t> {private list<t> array = new ArrayList <T> ();p ublic void Add (T item) {Array.add (item);} Public T get (int index) {return array.get (index);}} /// :~

9. Generic wildcard characters '? ' How to use it? '

Can be resolved when the specific type is uncertain, this wildcard is ? When an operation type is not required to use the specific functionality of the type, only the functionality in the object class is used. So you can use it? Wildcard character table unknown type.

For example Class<?>classtype = Class.forName ("java.lang.String");

Let's look at these programs first:

Code List 2

void Testgen0medthod1 (List l) {

for (Object o:l)

System.out.println (o);


See if this method has any objection, this method will be compiled, if you pass in a String, this is the list .

Then we call it, the problem arises, we pass a list as a list to the method, and the JVM gives us a warning that this is a compromise of type safety because the object type is returned from the list, and let's look at the following method.

Code List 3

void Testgen0medthod1 (List l) {

for (Object o:l)

System.out.println (o);


Because the list here is not a subclass of list , it is not a String-to-Object relationship, which means that list is not affiliated with List , they are not inheritance, so it is not possible, The extends here represents a limitation.

The type wildcard is amazing, List What can you do for him? "And it seems uncertain that he can't always return one?" As a type of data bar Yes he's not going to return a "? "To ask the programmer?" The JVM will do the simple thinking, look at the code, more intuitive.

Code List 4

List L1 = newarraylist ();

Li.add ("String");

List L2 = L1;

System.out.println (l1.get (0));

This code is no problem, L1.get (0) will return an object.

10. What is the expression of the generic limit (upper and lower limit)?

Ceiling:? Extends e: Can receive subtype objects of type E or E.

Lower:? Super E: You can receive the parent type object of type E or E.

cap When to use: when adding elements to the collection, you can either add an e-type object, or you can add a subtype object of E. Why? Because the E type can receive both the Class E object and the subtype object of E.

Low limit when to use: when fetching an element from a collection, it can be received with the current element's type, or it can be received with the parent type of the current element.

11. Can I use the base type as a generic parameter?

A generic type parameter can only be a class type (including a custom class) and cannot be a simple type (base data type).

12. When is the generic type used?

When the reference data type of an operation in an interface, class, and method is indeterminate, the previously used object is extended and can now be represented by generics. This avoids the hassle of a strong turn, and shifts the running issues to the compile time.

Details of generics:

1), generics exactly what type depends on the caller's incoming type, if not passed, the default is the object type;

2), when creating an object using a class with generics, the generic type specified on both sides of the equation must be consistent;

Cause: When the compiler checks the object to invoke the method, it only looks at the variables, but the object type is considered when the method is called during the program operation;

3), the equation can be used on either side of the generic type, on the other side is not used (consider backward compatibility);

Arraylist<string>al = new arraylist<object> (); // wrong

To ensure that the right and left sides of the generic type is consistent, it is not easy to make mistakes.

Arraylist<?extends object> al = new Arraylist<string> ();

Al.add ("AA"); // wrong

Because the collection-specific object can store either string or other subclasses of object, it is not appropriate to add a specific type object, and type checking can have a security problem. Extendsobject is an indeterminate subtype of object, how can I add objects of a specific type?

public static Voidmethod (arraylist<? extends Object> al) {

Al.add ("abc"); // wrong

The method in the object class can only be called on elements in the Al collection, and the methods of the specific subtypes are not available because the subtype is indeterminate.

13. What are the generics in the Java class library?

All standard collection interfaces are generic--collection<v>, list<v>, set<v>, and map<k,v>. Similarly, the implementation of the collection interface is generic with the same type parameters, so hashmap<k,v> implements Map<k,v> and so on.

In addition to the collection classes, there are several other classes in the Java class library that also serve as containers for values. These classes include WeakReference, SoftReference, and ThreadLocal.

14. Practice

Finish these two exercises:

Exercise One: Write an example that uses generics and does not use generic parameter arbitrariness. Code slightly

Exercise two: Modify, add a map<string,class<?>>, a AddType (String typename,class<?>kind) Method and a CreateNew () method. CreateNew () produces a new instance associated with its argument string, or generates an error message.

Package Generics;import Java.util.*;import static*;class Building {}class House extends Building {}public class classtypecapture21<t> {class<?> kind; Map<string, class<?>> map;public ClassTypeCapture21 (class<?> kind) {this.kind = kind;} Public ClassTypeCapture21 (class<?> kind, map<string, class<?>> map) {this.kind = Kind; = map;} public boolean F (Object Arg) {return kind.isinstance (ARG);} public void AddType (String typename, class<?> kind) {Map.put (typename, kind);} Public Object CreateNew (String TypeName) throws Illegalaccessexception, instantiationexception {if (Map.containskey ( TypeName)) return Map.get (TypeName). newinstance (); System.out.println (typename + "class not Available"); return null;} public static void Main (string[] args) {classtypecapture21<building> ctt1 = new classtypecapture21<building > (building.class);p rintln (ctt1.f (New Building ()));p Rintln (CTT1.F (New House ())); Classtypecapture21
15 References

Java1.5 Generic Guide Chinese version (Java1.5 Generic Tutorial)

Java generics in-depth explanation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.