Java basics-generics 2

Source: Internet
Author: User
Tags class definition

6 Type speculation

The Java compiler is able to examine all method invocations and corresponding declarations to determine the Type's arguments, that is, type speculation, and the Type's speculative algorithm guesses the most specific type of all parameters, as shown in the following example:

// declaration of a generic method Static return a2;} // call this method, based on the type of the assignment object, to speculate that the type parameter of the generic method is serializable // both string and arraylist<t> Implement interface serializable, the latter being the most specific type New Arraylist<string> ());
6.1 Type inference for generic methods

Type speculation can make the use of generic methods like normal methods without specifying the type within the angle brackets, as in the example Above.

6.2 Type inference for generic classes

For the use of generic classes, the Java compiler can also make type speculation, so when calling a generic class, you can not specify the type parameters within the angle brackets, but the angle brackets must not be omitted, the previous summary has been mentioned, the empty angle brackets are also called Diamonds (chinese strange), as shown in the following example:

// The following usage does not specify a type parameter and the angle brackets are empty New hashmap<>(); // Note that empty simple brackets cannot be omitted, and the following code compiler warns New HashMap ();

In the second assignment statement in the preceding code, the new HashMap () is actually the original type Used.

6.3 type parameter inference for generic constructors of non-generic classes

Classes that are generic or non-generic can use a generic constructor, as in a method.

// class definition class myclass<x> {  <T> MyClass (t t) {    //  ...   }}// The following is an expression that instantiates the above class , new myclass<integer> ("")

The instantiation expression in the above code does not specify a type parameter for the constructor, but it can be inferred that its type parameter is string based on the parameters passed IN.

Java7 Previous versions were able to speculate on the types of parameters that were constructed, and after java7, the syntax for using diamonds also speculated on the parameter types of the generic class.

It is important to note that the inference algorithm for type parameters only uses the passed-in parameters, the destination type, or the obvious return type to speculate on the Type.

6.4 Purpose Type

The Java compiler takes full advantage of the purpose type to speculate on the type parameters of a generic method or class, as in the following example:

// the declaration of a method in collections is as follows static <T> list<t> emptylist (); // now call the method list<string> Listone = collections.emptylist ();

In the second statement above, the Listone variable type is list<string>, which is the destination type, so the return type required by the method Emptylist must also be list<stirng> This makes it possible to speculate that T is string,java7 and 8 in a generic method declaration, and you can, of course, specify the type parameter in square brackets when calling a generic Method.

It is important to note that the parameters of the method in Java7 are not part of the destination type, while Java8 adds the method parameter to the destination type, as shown in the following example:

void processstringlist (list<string> stringlist) {    //    The signature of the Emptylist method in process stringlist}//collections is as follows static <T> list<t> emptylist (); // java7, The following call statements are compiled with an error, while JAVA8 does not have such a problem processstringlist (collections.emptylist ());
7 wildcard characters

In the generic code, the question mark (?) Represents wildcards, which represent unknown types, wildcards can be used as parameters, fields, and types of return values, but wildcard characters cannot be used as method calls, creation of generic instances, and arguments of a parent type.

7.1 Upper bound wildcard character

The limit of variables can be relaxed by using the upper bound wildcard Character.

The declaration method of the upper bound wildcard is shown in the following example:

public Static voidProcess (list<?extendsFoo> List) {/* ... */}

The above declared method, the generic parameter uses the upper bound wildcard, the wildcard character "?" The extends keyword is followed by its upper bound, where the extends is similar to extends and implements in the usual sense, meaning that the method is for a list of type number subtypes, including integer,float, and so On.

Wildcard < extends foo> matches all of the Foo's subtypes and foo type itself.

7.2 Unlimited wildcard characters

An unrestricted wildcard is a simple "?", such as list<?>, which represents a list of unknown types, and the following two scenarios are suitable for unrestricted wildcard characters:

    • When declaring a method to be used in an inherited object class
    • When a method of a generic class that does not depend on a type parameter is required in the code, such as list.size or list.clear, class<?> is often used because Many of the methods in class<t> are not dependent on the type parameter T.

The following example is a good illustration of the benefits of using unrestricted wildcard characters when using methods in the object Class:

 //  general method declaration   Public  static  void  printlist (List <object> list) { for   +" " //  a generic type that uses wildcards as a method parameter, the Method's parameters can be passed to any type of list  public  static  void  printlist (list<?> List) { for   (Object elem:list) System.out.print (elem  + "    "); System.out.println ();}  

Note: now that you have defined the generalized type of list list<?>, you have to assume the consequences of universality, in a method declaration you can only insert null for a variable of type list<?>, because you cannot predict the type variable of the incoming method, and list< Object> can be inserted into any type of object as a Parameter.

7.3 Lower bound wildcard character

Similar to the upper bound wildcard, the lower bound wildcard specifies the lower bound of the type parameter, the unknown type must be the parent type of the specified type, and the lower bound wildcard character:<? Super a> the keyword here is super.

Note: You cannot specify both upper and lower BOUNDS.

7.4 Wildcard characters and sub-types

As mentioned before, the relationships between generics are not just determined by their type arguments, such as List<number> is the parent of list<integer>, but using wildcards can form the following relationship:

The arrows indicate "is its subtype" relationship, such as list<integer> is list<? Extends integer> subtype, It can be understood that:list<integer> is a kind of list< Extends Integer>.

7.5 Methods of capturing and assisting wildcard characters

Sometimes the compiler guesses the type of the wildcard character, if the type of a field is defined as list<?>, and when an expression is being calculated, the compiler will infer from the code that the field is a specific type, which is called a wildcard capture.

Import java.util.List;  public class wildcarderror {    void foo (list<?> i) {        i.set (0, i.get (0));}    }

The above code compiles an error, the Foo method calls List.set (int,e), The compiler first treats the set method as the Parameter's I as the object type, cannot determine whether the object type to be inserted is consistent with the target list type, so the compilation does not pass.

At this point, you can add a helper method that will allow it to be compiled successfully:

 public class wildcardfixed {    void foo (list<?> i) {        foohelper (i);    }     // Create a helper method that calls the method to implement a wildcard capture    by type inference Private void foohelper (list<t> l) {        l.set (0, l.get (0));}    }

Let's take a look at one more example:

Import java.util.List;  public class Wildcarderrorbad {    voidextendsextends number> l2) {      = L1.get (0);      L1.set (0, l2.get (0));       L2.set (0, temp);}           }

The method function in the preceding code is to exchange the first element of the two list, but it is not possible to determine whether the type parameters of the two incoming arguments are compatible, so it cannot be compiled, and the code is inherently wrong, and there is no corresponding helper Method.

7.6 Wildcard Usage Principles

The use of generics is a bit confusing is not know when to use the upper bound wildcard, when to use the lower bound wildcard, a few principles:

To illustrate the problem, first list two variables 1) in variable: as the source of the data in the code, such as the copy method of the src parameter in copy (src,dest) is the in variable,; 2) out variable, used in code to store data as he uses, such as copy (src,dest) The Dest parameter in is the out Variable. After the variables are listed, say the principle:

    • The in variable uses the upper bound wildcard character, using the extends keyword
    • The out variable uses the lower bound wildcard character, using the Super keyword
    • Unrestricted wildcard characters are used when the in variable that needs to be used can be accessed through methods in the object class
    • Do not use wildcard characters when you need to access variables in your code both as in variables and as out variables

The above principle does not try with the return type of the method, it is not recommended to use wildcards in the return type, otherwise you will have to deal with the problem of wildcard Characters.

Java basics-generics 2

Related Article

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.