java- generic lower bound and an upper bound Detailed

Java Generics

Java generics (generics) is a new feature introduced in JDK 5, generics provide compile-time type safety detection mechanism, this mechanism allows programmers to detect illegal type at compile time.

 

Generic nature of the parameter type, data type that is being operated is specified as a parameter.

Suppose we have such a demand: to write a sorting method, able to array of integers, strings, arrays or even any other type of array to sort, how to achieve?

The answer is that you can use Java generics .

Use Java Generics, we can write a generic method for a array of objects sorted. Then, call the generic method to sort the array of integers, floating point arrays, an array of strings and the like.


Generic method

You can write a generic method that can receive different types of parameters when calling. The parameters passed to the method of the generic type, the compiler properly processed each method call.

The following is a generic method definition of rules:

  • All statements have a generic method type parameter statement portion (separated by angle brackets), the parameter type declaration section before the method return type (in the following example of <E> ).

  • Each type of parameter declaration portion comprises one or more types of parameters , the parameters are separated by commas. A generic parameter, also referred to as a variable type is used to specify the name of a generic type identifier.

  • Parameters can be used to declare the type of the return type , argument types, and can be used as placeholders for actual generic method obtained.

  • Declare a generic method and other methods, like body. Note that type parameter type can only represent a reference type, can not be a primitive type (like int, double, char, etc.).

Examples

The following example demonstrates how to use the elements of a generic method to print different strings:

public  class GenericMethodTest 
{ 
   // generic method printArray                          
   public  static <E> void printArray (E [] inputArray) 
   { 
      // output array element             
         for (E Element: inputArray) {         
            System.out.printf ( "% S" , Element) ; 
         } 
         System.out.println (); 
    } 
 
    public  static  void main (String args []) 
    { 
        // create different types of arrays: Integer, Double and Character 
        Integer [] = {intArray. 1, 2,. 3,. 4,. 5 } ; 
        Double [] doubleArray = {1.1, 2.2, 3.3, 4.4 }; 
        Character [] charArray = { 'H', 'E', 'L', 'L', 'O' }; 
 
        System.out.println ( "whole array elements: " ); 
        printArray (intArray); // pass an array of integers 
 
        System.out.println ( " \ n-double array elements: " ); 
        printArray (doubleArray); // send a double precision array 
 
        System.out.println ( "\ n-character array elements:" ); 
        printArray (charArray); // pass a character array 
    } 
}

 

 

Compile the above code, the results shown below:

Integer array elements:
 12,345 
double array elements: 1.1 2.2 3.3 4.4 
character array elements: 
HELLO 
 

 

Bounded type parameters

There may be times you will want to limit the scope of those types of species are allowed to pass a type parameter. For example, an operation of the digital approach may only want to accept or Example Number Number subclass. This is the purpose of bounded type parameters.

To declare a bounded type parameter, type the name of the parameter is listed first, followed by the extends keyword, followed by the last of its upper bound.

Examples

The following example demonstrates the "extends" How to use the means in a general sense "extends" (class) or "implements" (Interface). Generic methods in this example returns the maximum of three comparable objects.

 

public  class MaximumTest 
{ 
   // comparison and returns the maximum value of the three 
   public  static <T the extends the Comparable <T >> T maximum (T x, T Y, T Z) 
   {                      
      T max = x; // assume that x is the initial maximum value 
      IF (y.compareTo (max)> 0 ) { 
         max = Y; // Y greater 
      }
       IF (z.compareTo (max)> 0 ) { 
         max = z; // now greater z            
      }
       return max; // returns the maximum target 
   }
    public static  void main (String args []) 
   { 
      System.out.printf ( "% d,% d% d and the maximum number of% d \ n-\ n-" ,
                    . 3,. 4,. 5, maximum (. 3,. 4, . 5 )); 
 
      System.out.printf ( "% .1f, and the% .1f% .1f maximum number% .1f \ n-\ n-" ,
                    6.6, 8.8, 7.7, maximum (6.6, 8.8, 7.7 ) ); 
 
      System.out.printf ( "% s,% s% s, and the maximum number of% s \ n-", "PEAR" ,
          "Apple", "Orange", maximum ( "PEAR", "Apple", "Orange" )); 
   } 
}

 

 

Compile the above code, the results shown below:

3, 4 and 5, the maximum number of 5 or 6.6, 8.8 and 7.7 for the maximum number of 8.8 
pear, orange Apple and pear largest number

 


Different parameter types have similar manner

Generic class

And non-generic type declarations statements generic class is similar, except that the added after the class name parameter type declaration section .

And generic methods as part of a generic class type parameter declaration may also contain one or more types of parameters, the parameters are separated by commas. A generic parameter, also referred to as a variable type is used to specify the name of a generic type identifier. Because they accept one or more parameters, these classes are called parameterized classes or parameterized type.

Examples

The following examples demonstrate how we define a generic class:

public class Box<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
    //添加修饰
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
 
    integerBox.add(new Integer(10));
    stringBox.add(new String("字符"));
 
    System.out.printf ( "Integer value:% D \ n-\ n-" , integerBox.get ()); 
    System.out.printf ( "string is:% S \ n-" , stringBox.get ()) ; 
  } 
}

 

 

Compile the above code, the results shown below:

Integer values are: 10 
string: Character

 


Different classes have similar parameters, and similar methods

Wildcard type

1, type wildcard generally use? Instead of a specific type parameters . For example, List is logically List, List and all List <particular type arguments> parent.

Example 1

ublic class CommonSingle {
    public static  void printer(List<?> data) {//普通的
        System.out.print(data);
    }
    public static void getUperNumber(List<? extends Number> data) {//给通配符划分了范围
         System.out.println("data :" + data);
      }
}
    List<String> name = new ArrayList<String>();
            List<Integer> age = new ArrayList<Integer>();
            List<Number> number = new ArrayList<Number>();
            
            name.add("icon");
            age.add(18);
            number.add(314);
     
            CommonSingle.printer(name);
            CommonSingle.printer(age);
            CommonSingle.printer(number);

 

The output is:

data :icon
data :18
data :314

 

Resolution:

1, because the parameters getData () method of the type is List, the name, age, number of this argument can be used as a method, this is the role of wildcards

2, List Type wildcards limit defined by the form, so defined is the wildcard value accepted generic subclasses Number and type underlayer.

3, a generic method is similar to the first, choose something different methods according to the parameter type, the parameter type is simply wrapped List.

Example 2

Continue to use the previously declared class CommonSingle

 List<String> name = new ArrayList<String>();
            List<Integer> age = new ArrayList<Integer>();
            List<Number> number = new ArrayList<Number>();
            
            name.add("icon");
            age.add(18);
            number.add(314);
            CommonSingle.getUperNumber(name);//报错:因为S不在Number的范围内
            CommonSingle.getUperNumber(age);
            CommonSingle.getUperNumber(number);

 

 

Output:

Date: 18 
Year: 314

 

Resolution:

1, at (1 //) error occurs, because getUperNumber () method of the generic parameters have been defined parameter limit to Number, it is away String generics within this range, it will be given

2, by forming the lower limit as a wildcard type List is defined, representing the type and only accept Example Number three parent type, such as type Object.

3, upper limit, ? extends Numbersubclasses Number class as follows:

java.lang.Byte, 
java.lang.Double, 
java.lang.Float, 
java.lang.Long, 
java.lang.Short

 

This is? Parameters.

 

4, on the upper bound lower bound

list the world can only get, can not add (or rather not add the objects other than null, including Object)

The lower bound of the list can only add, can not get

add and get related to specific types of data:

add method is to give a pre-object is added to create a reference , let the reference points to a particular parent class or subclass object;

get method is returned concrete classes (assuming type 1), there must be a type 1 or type parent to a reference to it ;

Specifies the upper bound: If you add add objects, java do not know what you want to add a reference to a specific class, but java is not automatically selected; if get an object, it can (artificially) the use of boundary class to create references (because the code specified upper bound, see the answer).

The predetermined lower bound: if add add objects, java do not know which add a reference to a particular class, there can be (artificially) was added subclass object class of the lower bound (the lower bound since the predetermined code, see at a glance) ; If you get an object, the class can only use pre-fetched 'similar' or create a reference to the parent class, but the programmer does not know which get out of class.

Graphic:

image-20200401005404679


image-20200401010056003

Sample code:

import java.util.ArrayList;
import java.util.List;
  
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
  
public class CovariantArrays {
  public static void main(String[] args) {
    //上界
    List<? extends Fruit> flistTop = new ArrayList<Apple>();
    flistTop.add(null);
    //add Fruit对象会报错
    //flist.add(new Fruit());
    Fruit fruit1 = flistTop.get(0);
  
    //下界
    List<? super Apple> flistBottem = new ArrayList<Apple>();
    flistBottem.add(new Apple());
    flistBottem.add(new Jonathan());
    //get Apple对象会报错
    //Apple apple = flistBottem.get(0);
  }
}

 

 

Guess you like

Origin www.cnblogs.com/1605-3QYL/p/12609999.html