Java basics-generic 2, basic generic java

Source: Internet
Author: User

Java basics-generic 2, basic generic java
6. Speculation

The java compiler can check all method calls and corresponding declarations to determine the real parameters of the type, that is, type speculation. The speculative algorithm of the type determines the most specific types of all parameters, as shown in the following example:

// Declaration of generic methods static <T> T pick (T a1, T a2) {return a2;} // call this method based on the type of the assigned object, it is estimated that the type parameters of the generic method are Serializable // String and ArrayList <T>. The latter is the most specific type. Serializable s = pick ("d ", new ArrayList <String> ());
6.1 Type Estimation of generic methods

The speculative type can make the usage syntax of the generic method the same as that of the common method. You do not need to specify the type in the angle brackets, as shown in the preceding example.

6.2 Type Estimation of generic classes

For the use of generic classes, the java compiler can also speculate on the types. Therefore, when calling generic classes, you do not need to specify the type parameters in angle brackets. However, angle brackets cannot be omitted, as mentioned above, empty angle brackets are also called Diamond (Chinese), as shown in the following example:

// No type parameter is specified in the following usage. The angle brackets are empty. Map <String, List <String> myMap = new HashMap <> (); // note that, empty parentheses cannot be omitted. The following code compiler will issue a warning Map <String, List <String> myMap = new HashMap ();

In the second value assignment statement in the above Code, new HashMap () is actually the original type.

6.3 type parameter estimation of non-generic Constructors

Generic constructors can be used for both generic and non-generic classes, just like methods.

// Class definition class MyClass <X >{< T> MyClass (T t ){//...}} // The following is the expression for instantiating the above class new MyClass <Integer> ("")

Although the instantiation expression in the above Code does not specify the type parameter of the constructor, it can be inferred that the type parameter is String based on the input parameter.

In versions earlier than Java 7, the parameter types of the constructed class can be inferred. In Versions later than Java 7, the diamond syntax is used to speculate on the parameter types of the generic class.

It should be noted that the speculative algorithm of the type parameter only uses the input parameter, the target type or obvious return type to speculate on the type.

6.4 target type

The java compiler makes full use of the target type to speculate on the type parameters of generic methods or classes, as shown in the following example:

// The declaration of a method in Collections is as follows: static <T> List <T> emptyList (); // call the method List <String> listOne = Collections. emptyList ();

In the second statement above, the listOne variable type is List <string>, which is the target type. Therefore, the return type of the emptyList method must also be List <Stirng>, in this way, we can speculate that T in the generic method declaration is String, Java 7 and 8 can both implement such speculation. Of course, you can refer to the type parameter in square brackets when calling the generic method.

It is worth noting that the method parameters in Java 7 do not belong to the target type, while Java 8 adds the method parameters to the target type, as shown in the following example:

// The parameters accepted in the following method are List <String> void processStringList (List <String> stringList) {// process stringList} // The emptyList method signature in Collections is as follows: static <T> List <T> emptyList (); // In java7, an error is reported when compiling the following call statements, processStringList (Collections. emptyList ());
7 wildcard characters

Question mark (?) in generic code (?) A wildcard represents an unknown type. a wildcard can be used in many cases as a parameter, field, or return value. However, a wildcard cannot be used as a method call, create a wildcard instance and a real parameter of the parent type.

7.1 upper limit wildcard

Use the upper limit wildcard to relax the restriction on variables.

The following is an example of how to declare an upper limit wildcard:

Public static void process (List <? Extends Foo> list ){/*...*/}

In the method declared above, the wildcard parameter uses the upper limit wildcard, the wildcard "? "Add the extends keyword followed by its upper limit. Here, extends is similar to extends and implements in the general sense, meaning that this method is for the Number type subtype, including the list of Integer, Float, and so on.

Wildcard<? Extends Foo> matches the child types of all Foo and the Foo type itself.

7.2 unlimited wildcard characters

Unlimited wildcard is simple "? ", Such as List <?> The list of unknown types. The following two conditions are suitable for unlimited wildcard characters:

  • When declaring a method in the inherited Object class
  • When the code needs to use methods of generic classes that do not depend on type parameters, suchList. sizeOrList. clear,WhileClass <?>It is often used becauseClass <T>Many methods in are independent of the type parameter T.

The following example demonstrates the benefits of using an unlimited wildcard when using methods in the Object class:

// General method declaration public static void printList (List <Object> list) {for (Object elem: list) System. out. println (elem + ""); System. out. println ();} // use wildcard as the method parameter. This method parameter can be used to input a List of all types (List) public static void printList (List <?> List) {for (Object elem: list) System. out. print (elem + ""); System. out. println ();}

Note: The List is defined. <?> The wide range of types, it is necessary to bear the consequences of extensive, in the method declaration, only the List <?> Type variables insert null, because you cannot predict the type variables of the input method, and List <Object> as a parameter can insert any type of objects.

7.3 lower limit wildcard

Similar to the upper limit wildcard, the lower limit wildcard specifies the lower limit of the type parameter. The unknown type must be the parent type of the specified type. The lower limit wildcard is written as follows:<? Super A>. The keyword here is super..

Note: The upper and lower limits cannot be specified simultaneously.

7.4 wildcard and child Type

As mentioned before, the relationship between generics is not only determined by their type parameters, for example, List <Number> is the parent class of List <Integer>, however, wildcards can form the following relationships:

The arrow indicates the relationship "is its subtype", for example, List <Integer> is List <? The sub-type of extends Integer>, which can be understood as follows: List <Integer> is a List <? Extends Integer>.

7.5 wildcard capturing and auxiliary methods

Sometimes the compiler speculate on the type of the wildcard. If the type of a field is defined as List <?>, When calculating an expression, the compiler will speculate from the code that this field is of a specific type, which is called the capture of wildcards.

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

 

The above code will cause compilation errors. The foo method calls List. set (int, E), the compiler first regards the I as the parameter in the set method as the Object type, and cannot determine whether the Object type to be inserted is consistent with the target list type, therefore, compilation fails.

In this case, you can add an auxiliary method so that it can be compiled smoothly:

Public class WildcardFixed {void foo (List <?> I) {fooHelper (I);} // create an auxiliary method. You can call this method to capture the private wildcard through type speculation. <T> void fooHelper (List <T> l) {l. set (0, l. get (0 ));}}

Let's take a look at the next example:

import java.util.List;public class WildcardErrorBad {    void swapFirst(List<? extends Number> l1, List<? extends Number> l2) {      Number temp = l1.get(0);      l1.set(0, l2.get(0));       l2.set(0, temp);           }}

The method function in the above Code is to exchange the first element of the two lists. However, it is impossible to determine whether the type parameters of the two passed arguments are compatible. Therefore, compilation fails, the code here is essentially incorrect and there is no auxiliary method.

7.6 wildcard usage principles

The usage of generics is a bit confusing: I don't know when to use the upper limit wildcard and when to use the lower limit wildcard. The following are some principles:

To illustrate the problem, first list two variables. 1) In variables: as the data source in the Code, for example, the src parameter In the copied method copy (src, dest) is the in variable; 2) the out variable is used in the code to store data for other purposes. For example, the dest parameter in copy (src, dest) is the out variable. After the variables are listed, the principle is as follows:

  • The in variable uses the upper limit wildcard and the extends keyword.
  • The out variable uses the lower limit wildcard and the super keyword.
  • When the in variable to be used can be accessed through the method in the Object class, use the unrestricted wildcard
  • Do not use wildcards when the variables to be accessed in the Code are used as in variables and out variables.

We do not recommend that you use wildcards in the return type. Otherwise, you must handle the problem of wildcards.

 

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.