Consolidate one of Java's basic--generic details (1)

Source: Internet
Author: User
Tags define abstract function definition gety uppercase letter

No matter when, believe in yourself.


Related articles:

1, "tamping java one of the basic--generic detailed (1)"
2, "tamping java one of the basic--generic detailed (2)"

first, the introduction

1. What is a generic type?First tell everyone that ArrayList is a generic type. What can the ArrayList do with unexpected functions? Let's take a look at the following code:

arraylist<string> strlist = new arraylist<string> (); arraylist<integer> intlist = new arraylist<integer> (); arraylist<double> doublelist = new arraylist<double> ();
Everyone is familiar with ArrayList, which constructs three lists, each containing string, integer and double; This is what ArrayList is all about: variables of various types can be assembled into the corresponding list, Instead of implementing a class that builds ArrayList for each type, respectively. Here may not understand, the opening is always difficult, below to see if there is no generics, we have to do;
2, no generics will be howLet's look at the following code:
We implement two classes that can set point coordinates, set the point coordinates of the integer type and the point coordinates of the float type, respectively:
Sets the point coordinate of the Integer type class integerpoint{    private Integer x;       Represents the x-coordinate    private Integer y;       Represents the y    -coordinate public void SetX (Integer x) {        this.x = x;    }    public void Sety (Integer y) {        this.y = y;    }    Public Integer GetX () {        return this.x;    }    Public Integer GetY () {        return this.y;    }} Sets the point coordinate of the Float type class floatpoint{    private Float x;       Represents the x-coordinate    private Float y;       Represents the y    -coordinate public void SetX (Float x) {        this.x = x;    }    public void Sety (Float y) {        this.y = y;    }    Public Float GetX () {        return this.x;    }    Public Float GetY () {        return this.y;    }}
Now there is a question: Have you found that they are not the same as the variable type, one is the integer one is float, the other is no different! So can we merge into one?
The answer is yes, because both the integer and float are derived from object, and we use the following code instead:
Class objectpoint{    private Object x;    Private Object y;    public void SetX (Object x) {        this.x = x;    }    public void Sety (Object y) {        this.y = y;    }    Public Object GetX () {        return this.x;    }    Public Object GetY () {        return this.y;    }}
That is, all use object to replace all subclasses;
In use, this is the case:
Objectpoint integerpoint = new Objectpoint (); integerpoint.setx (new integer); integer integerx= (integer) Integerpoint.getx ();
When setting up, use new Integer (100) to create an integer
Integerpoint.setx (New Integer (100));
Then, when the value is taken, a cast is made:
Integer integerx= (integer) integerpoint.getx ();
Since we are setting the integer, the cast is not an error when the value is taken.
Similarly, the settings and values of the floatpoint are similar, and the code is as follows:
Objectpoint floatpoint = new Objectpoint () Floatpoint.setx (new Float (100.12f)); float floatx = (float) floatpoint.getx ();
But here's the problem: note, note that we're using a cast here, we're setx () and Getx () here, so we know exactly what we're going to do with the float type, so what if we're mistaken?
For example, if we change to the following, the compile will be error:
Objectpoint floatpoint = new Objectpoint () Floatpoint.setx (new Float (100.12f)); String floatx = (string) floatpoint.getx ();
No!!! The key to our problem lies in this sentence:
String floatx = (string) floatpoint.getx ();
When casting, there will be no error. Because the compiler does not know what you are passing in, and Floatpoint.getx () returns the type object, so when compiling, the object is strongly turned into a string. Must not be an error.
And at run time, otherwise, at run time, floatpoint instance is passed in the variable of float type, do not want to turn it to string type, certainly will report type conversion wrong!
Is there a way in the compile phase, that can be merged into the same, but also at compile time to check out the type is wrong? This, of course, is generics.
Below we will explain the wording and usage of generics one by one.
II. definitions and use of generic types

1. Generic class definition and usageLet's start by looking at how generic classes are defined:

Define class point<t>{//Here you can write the identity symbol     private T x;          Private T y;          public void SetX (T x) {//as parameter        this.x = x;    }    public void Sety (T y) {        this.y = y;    }    Public T GetX () {//As return value        this.x;    }    Public T GetY () {        return this.y;    }};/ /integerpoint using point<integer> p = new point<integer> (); P.setx (New Integer (100)); System.out.println (P.getx ());  Floatpoint using point<float> p = new point<float> (); P.setx (New Float (100.12f)); System.out.println (P.getx ());  
First look at the results of the operation:

As you can see from the results, we realized the effect of the Integerpoint class and the Floatpoint class in the opening. Let's take a look at how generics are defined and used.

(1), define generic:point<t>
First of all, you can see POINT<T>, that is, after the class name with an angle bracket, in parentheses is a capital letter. Here is the T, in fact, this letter can be any capital letter, we first remember, can be any capital letter, meaning is the same.
(2) Use Generics in class
This t represents any class derived from the object class, such as string,integer,double, and so on. It is important to note that T must be derived from the object class. For convenience, you can use T as a string here, that is, how string is used in a class, and how it can be used in a class! So the following: defining variables, as return values, is easy to understand as the definition passed in as a parameter.

Define the variable private T x; As the return value public T GetX () {     return x;  }  As parameter public void SetX (T x) {      this.x = x;  
(3) using generic classes
The following is the use of generic classes:
Integerpoint using point<integer> p = new point<integer> (); P.setx (New Integer (100)); System.out.println (P.getx ());  Floatpoint using point<float> p = new point<float> (); P.setx (New Float (100.12f)); System.out.println (P.getx ());  
First, an example is constructed:
The difference between this and the ordinary constructed class instance is that the normal class constructor is this: point p = new dot ();
The construction of a generic class requires the addition of a &LT;STRING&GT after the class name, that is, a pair of angle brackets, and the middle writes the type to be passed in.
Because when we construct it, it is this: class Point<t&gt, so when you use it, you also add a type to the point to define the meaning of the T representation.
Then there is nothing special in GetVar () and Setvar (), which can be called directly.
From the above, you can clearly see the role of generics, when constructing instances of a generic class:
In angle brackets, what you pass in, T is what type. This is the biggest function of generics, we just need to consider the logical implementation, we can give the various classes to use.
We mentioned earlier that ArrayList is also generic, and we have by the way its implementation:
public class arraylist<e>{......}
See, it's the same as our point implementation, which is why ArrayList is able to dress up the main reasons for various types.
(4) Benefits of using generic implementations
There are two advantages to using object at the outset:
(1), no forced conversion

(2), at Settvar () if the incoming type is wrong, compile error

As you can see, when we construct a string, and when we setvar it, we get an error when we pass in the integer type. Instead of being quoted as an object implementation, a cast error is reported at run time.

2. Multi-generic variable definition and letter specification (1), multi-generic variable definition
On the We have only defined a generic variable t, so what if we need to pass in more than one generic type?
You just have to do something like this:

Class morepoint<t,u>{}
That is, after the original T with a comma separated, write any other capital letters can be. To add a few, for example, we want to add five generic variables, that should be the case:

Class morepoint<t,u,a,b,c>{}
For a chestnut, we'll add a field to the point name, which is also represented by generics, so what do we do? The code is as follows:
Class Morepoint<t,u> {    private T x;    Private T y;           private U name;    public void SetX (T x) {        this.x = x;    }    Public T GetX () {        return this.x;    }    ....... public void SetName (U name) {        this.name = name;    }    Public U GetName () {        return this.name;    }} Use morepoint<integer,string> morepoint = new Morepoint<integer, string> (); Morepoint.setname ("Harvic"); LOG.D (TAG, "morpont.getname:" + morepoint.getname ());
As you can see from the code above, the new generic variable u usage is the same as T.
(2), letter specification
When defining a generic class, we have already mentioned that the variable used to specify the generic is an uppercase letter:
Class point<t>{......}
Of course not!!! Any uppercase letter is allowed. Their meaning is exactly the same, but in order to improve readability, it is better to use meaningful letters, generally speaking, the meanings of letters used in different contexts are as follows:
    • E-element, commonly used in Java collection, such as:list<e>,iterator<e>,set<e>
    • K,v-key,value, which represents the key value pair for map
    • N-number, Digital
    • T-type, type, such as String,integer, etc.
If this is not enough, then take it yourself, anyway, 26 English letters.
Again, it doesn't make sense to use which letter! Just to improve readability!!!!
3, generic interface definition and use

Defining generics on an interface is the same as defining generics in a class, with the following code:

Interface info<t>{        //define generic public      T GetVar () on the interface,//define abstract methods, the return value of the abstract method is the generic type public      void SetVar (T x);}  

As with the definition of a generic class, an angle bracket is also added to the interface name;
(1), use method one: non-generic class
But in the use of the time, there is a problem, we first look at the following method of use:

Class Infoimpl implements info<string>{//defines the subclass of the generic interface    private String var;//Defines the property public    Infoimpl (String var {//Set property content        This.setvar (Var) by construction method;    }    @Override public    void SetVar (String var) {        This.var = var;    }    @Override public    String GetVar () {        return this.var;    }} public class genericsdemo24{    public  void Main (String arsg[]) {        Infoimpl i = new Infoimpl ("Harvic");        System.out.println (I.getvar ());}    ;
First, let's look at the definition of Infoimpl:
Class Infoimpl implements info<string>{......}
The point to be clear is that Infoimpl is not a generic class! Because he has no <t>! after his class name.
Then in here we'll fill in the generic variable t definition in info<string> to the String type. So when you rewrite Setvar () and GetVar (), the IDE also generates a string-type override function directly.
Finally, in use, there is no difficulty in passing in string strings to construct the Infoimpl instance, and then call its function.
public class genericsdemo24{    public  void Main (String arsg[]) {        Infoimpl i = new Infoimpl ("Harvic");        System.out.println (I.getvar ());}    ;
(2), use method two: generic type

In method One, we populate the Info<t> interface directly in the class, but our class can be constructed into a generic class, so what happens if we use a generic class to construct a filled generic interface?

Interface info<t>{//defines the generic public T GetVar () on the interface,//defines the abstract method, the return value of the abstract method is the generic type public void SetVar (T var);} Class Infoimpl<t> implements info<t>{//defines the subclass of the generic interface private T var;//Define Properties Public Infoimpl (T var) {//Set property contents by constructor method This.setvar (Var);} public void SetVar (T var) {this.var = var;} Public T GetVar () {return this.var;}} public class Genericsdemo24{public static void Main (String arsg[]) {infoimpl<string> i = new infoimpl<string> ("Harvic"); System.out.println (I.getvar ());};

The most critical is the process of constructing a generic class:
Class Infoimpl<t> implements info<t>{//defines the subclass of the generic interface private T var;//Define Properties Public Infoimpl (T var) {//Set property contents by constructor method This.setvar (Var);} public void SetVar (T var) {this.var = var;} Public T GetVar () {return this.var;}}
In this class, we construct a generic class Infoimpl<t&gt, and then pass the generic variable T to Info<t&gt, which means that both the interface and the generic class use the same generic variable.
Then, when used, is the process of constructing an instance of a generic class, with the same process.
public class Genericsdemo24{public static void Main (String arsg[]) {info<string> i = new Infoimpl<string> (" Harvic "); System.out.println (I.getvar ());};
The purpose of inheriting a generic interface with a generic class is to let the user define the type of variable used by the interface, rather than writing to the class in the same way as method one.
Let's just slightly deepen the difficulty, construct a class of multiple generic variables, and inherit from the info interface:
Class Infoimpl<t,k,u> implements info<u>{//defines the subclass of the generic interface,     private U var;     Private T x;     Private K y;     Public Infoimpl (U var) {//Set property content         This.setvar (Var) by constructing method;     }     public void SetVar (U var) {         This.var = var;     }     Public U GetVar () {         return this.var;     }}
In this example, we define three generic variable t,k,u in a generic class and use the third generic variable U to populate interface info. So in this example, the type used by info is determined by U.
Use this: the basic use of generic classes, no longer speak more, the code is as follows:
public class genericsdemo24{    public  void Main (String arsg[]) {        infoimpl<integer,double,string> i = new Infoimpl<integer,double,string> ("Harvic");        System.out.println (I.getvar ());}    }
4. Definition and use of generic functionsHere we explain the generic use of classes and interfaces, and let's say how generics are used in a function alone. For example, we are creating a common class Staticfans, and then we define two generic functions in it:
public class Staticfans {//static function public    static  <T> void Staticmethod (T a) {        log.d ("Harvic", " Staticmethod: "+a.tostring ());    } normal function    public  <T> void Othermethod (T a) {        log.d ("Harvic", "Othermethod:" +a.tostring ());}    }
The above is the definition of static generic functions and regular generic functions, and the only difference from previous methods is to add <T> to represent generic variables before the return value. No other difference.
Here's how to use it:
static method Staticfans.staticmethod ("ADFDSA");//Use Method one Staticfans.<string>staticmethod ("ADFDSA");//Use Method two// General method Staticfans Staticfans = new Staticfans () Staticfans.othermethod (new Integer (123));//use method one Staticfans.<integer >othermethod (New Integer (123));//Use Method two
The results are as follows:

First, let's look at how static generic functions are used:

Staticfans.staticmethod ("ADFDSA");//Use Method one Staticfans.<string>staticmethod ("ADFDSA");//Use Method two
From the results we can see that the results of the two methods are exactly the same, but they also have some differences, the difference is as follows:
Method One, you can pass the value directly, like a normal method, any value can (but must be derived from the type of the object class, such as String,integer, etc.), the function will internally according to the parameters passed in to identify the current T category. But try not to use this implicit way of passing, code is not conducive to reading and maintenance. Because it doesn't look like you're calling a generic function.
Method Two, which differs from the method, is that a <String> is added before the method is called to specify the value passed to <T>, if this <String> is added to specify the value of the parameter, The type of t used in the Staticmethod () function is forced to specify the string type. This is the way we recommend it.
Similarly, there are two ways to use regular generic functions:
Staticfans Staticfans = new Staticfans () Staticfans.othermethod (new Integer (123));//use method one staticfans.<integer> Othermethod (New Integer (123));//Use Method two
As you can see, you create an instance of the class first, and then call the generic function.
Method One, implicitly passing the type of T, as above, it is not recommended to do so.
Method two shows the assignment of T to the integer type, so that the argument passed by Othermethod (t a) if it is not an integer then the compiler will give an error.

Advanced : Generics exist in the return value
In our function above, the return value is void, but in reality it is not all void, and sometimes we need to return the generic variable, such as the following function:
public static <T> list<t> Parsearray (String response,class<t> object) {    list<t> modellist = Json.parsearray (Response, object);    return modellist;}
The function return value is the list<t> type. As for the meaning of the incoming parameter class<t> object, we'll talk about it below. Here also is to let this example to tell you that the generic variable actually with string,integer,double and so on the use of the class is not any different, T is just a symbol, can represent string,integer,double ... The symbols of these classes, when used in generic functions, directly see the T-string,integer,double ... Any one of them to write the code. The only difference is to add the <T> identity generic to the function definition before the return value.
5. Other usages:class<t> class transfer and generic array (1), using class<t> to pass generic class object
Sometimes we encounter a situation where, for example, we use JSON to parse a string, the code is usually like this

public static list<successmodel> Parsearray (String response) {    list<successmodel> modellist = Json.parsearray (response, successmodel.class);    return modellist;}
Where Successmodel is a custom parsing class, the code below, in fact, we do not have to control the definition of Successmodel, only consider the above code on the line. Write out Successmodel code, just don't want everyone to feel confused, in fact, here is just the basic usage of Fastjson.
The meaning of this code is to parse the list<successmodel> array according to Successmodel.
public class Successmodel {    private Boolean success;        public Boolean issuccess () {        return success;    }    public void Setsuccess (Boolean success) {        this.success = success;    
Now, let's assemble the following sentence into a generic function.
public static list<successmodel> Parsearray (String response) {    list<successmodel> modellist = Json.parsearray (response, successmodel.class);    return modellist;}
First of all, we should take successmodel alone as a generic variable, but how do you get the Successmodel.class used in Parsearray ()?
First look at the code:
public static <T> list<t> Parsearray (String response,class<t> object) {    list<t> modellist = Json.parsearray (Response, object);    return modellist;}
Notice that we use the Class<t> object to pass the class object, which is the successmodel.class we mentioned above.
This is because class<t> is also a generic type, which comes from a class object that is used to load classes, which is defined as follows:
Public final class Class<t> implements Serializable {......}
The question of loading a generic class object through class<t> is done, so let's look at how to use the generic array.
(2), defining a generic array
When writing a program, you may encounter a requirement like string[] list = new String[8], where you can define a String array, and of course we can define a generic array, the definition of a generic array is t[], which is consistent with string[], and look at the usage:

Define public static <T> t[] Fun1 (t...arg) {  //Receive variable parameter         return arg;            Returns a generic array  }  //Using public static void Main (String args[]) {         Integer i[] = fun1 (1,2,3,4,5,6);       Integer[] result = FUN1 (i);}  
Let's look at the code at the time of definition:
public static <T> t[] Fun1 (t...arg) {  //Receive variable parameter         return arg;            Returns a generic array  }  
First, a static function is defined, and then a variable-length parameter of the type T that is received is defined with a return value of t[]. If you have classmates who do not understand the use of t...arg, you can find the Java variable length parameters of knowledge.
Since the variable-length parameter is entered, it is saved in the ARG array, so we can return the array directly.

Well, this is the end of this article, which is mainly about generics in all aspects of the definition and usage, the next chapter, we will tell about the generic qualification related knowledge.

If this article has helped you, remember to pay attention to OH

This article is concerned with source code: http://download.csdn.net/detail/harvic880925/9275047

Please respect the original copyright, reproduced please indicate the source oh: http://blog.csdn.net/harvic880925/article/details/49872903 Thank you.


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Consolidate one of Java's basic--generic details (1)

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: info-contact@alibabacloud.com 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.