Getting started with Java - advanced tutorial - 03. Generics

Keywords: Java JDK

Original address: http://www.work100.net/training/java-generic.html
More tutorials: Beam cloud - free course

generic paradigm

Serial number Chapter in text video
1 Summary -
2 generic method -
3 Generic class -
4 Type wildcard -

Please refer to the navigation above for reading

1. overview

Java generics is a new feature introduced in JDK 5. Generics provides a compile time type security detection mechanism, which allows programmers to detect illegal types at compile time.
The nature of generics is parameterized type, that is, the data type being manipulated is specified as a parameter.

Suppose we have such a requirement: write a sort method, which can sort integer array, string array or any other type of array. How to implement it?
The answer is that you can use Java generics.
Using the concept of Java generics, we can write a generic method to sort an array of objects. Then, the generic method is called to sort the integer array, floating-point array, string array, etc.

2. Generic methods

You can write a generic method that receives different types of arguments when it is called. Depending on the type of parameter passed to the generic method, the compiler handles each method call appropriately.

Here are the rules for defining generic methods:

  • All generic method declarations have a type parameter declaration part (separated by angle brackets) that precedes the method return type (in the following example & lt; E & gt;)
  • Each type parameter declaration part contains one or more type parameters separated by commas. A generic parameter, also known as a type variable, is an identifier used to specify a generic type name
  • Type parameters can be used to declare return value types and can be used as placeholders for actual parameter types obtained by generic methods
  • Generic method bodies are declared the same as other methods. Note that type parameters can only represent reference type, not original type (such as int,double,char, etc.)

Example

The following example shows how to use generic methods to print elements of different strings:

public class GenericMethodTest
{
   // Generic method printArray                         
   public static <E> void printArray( E[] inputArray )
   {
      // Output array elements            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }

    public static void main( String[] args )
    {
        // Create arrays of different types: 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( "Integer array elements are:" );
        printArray( intArray  ); // Pass an integer array

        System.out.println( "\n The elements of the double precision array are:" );
        printArray( doubleArray ); // Pass a double array

        System.out.println( "\n Character array elements are:" );
        printArray( charArray ); // Pass a character array
    } 
}

Compile the above code and run the result as follows:

The elements of an integer array are:
1 2 3 4 5 

The elements of the double precision array are:
1.1 2.2 3.3 4.4 

Character array elements are:
H E L L O 

Bounded type parameters:

Sometimes, you may want to limit the range of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number or Number subclasses. This is the purpose of bounded type parameters.

To declare a bounded type parameter, first list the name of the type parameter, followed by the extends keyword, and then the upper bound.

Example

The following example demonstrates how "extensions" can be used to mean "extensions" (classes) or "implements" (interfaces) in a general sense. The generic method in this example returns the maximum value of three comparable objects.

public class MaximumTest
{
   // Compare three values and return the maximum
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // Assume x is the initial maximum
      if ( y.compareTo( max ) > 0 ){
         max = y; //y bigger
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // Now z is bigger           
      }
      return max; // Return maximum object
   }
   public static void main( String[] args )
   {
      System.out.printf( "%d, %d and %d The maximum number in is %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );

      System.out.printf( "%.1f, %.1f and %.1f The maximum number in is %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );

      System.out.printf( "%s, %s and %s The maximum number in is %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

Compile the above code and run the result as follows:

The maximum number of 3, 4 and 5 is 5

The maximum number in 6.6, 8.8 and 7.7 is 8.8

pear, apple and orange have the largest number of pear

3. generic class

The declaration of a generic class is similar to that of a non generic class, except that the type parameter declaration part is added after the class name.

As with generic methods, the type parameter declaration part of a generic class contains one or more type parameters separated by commas. A generic parameter, also known as a type variable, is an identifier that specifies the name of a generic type. Because they accept one or more parameters, these classes are called parameterized classes or parameterized types.

Example

The following example shows how to 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("Beam cloud intelligence"));

    System.out.printf("Integer value is :%d\n\n", integerBox.get());
    System.out.printf("String is :%s\n", stringBox.get());
  }
}

Compile the above code and run the result as follows:

Integer value: 10

The string is: beam cloud intelligence

4. Type wildcard

1) . type wildcards generally use? Instead of specific type parameters. For example, list & lt;? & gt; is logically the parent class of all list & lt; concrete type arguments & gt; such as LIS & lt; string & gt;, list & lt; integer & gt.

import java.util.*;

public class GenericTest {

    public static void main(String[] args) {
        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);

        getData(name);
        getData(age);
        getData(number);

   }

   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
}

The output result is:

data :icon
data :18
data :314

Parsing: because the parameters of getData() method are of type List, name, age and number can be used as arguments of this method, which is the function of wildcard

2) . the upper limit of type wildcard is defined by the shape such as List, so the definition is that the wildcard generic value accepts Number and its lower level subclass types.

import java.util.*;

public class GenericTest {

    public static void main(String[] args) {
        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);

        //getUperNumber(name);//1
        getUperNumber(age);//2
        getUperNumber(number);//3

   }

   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }

   public static void getUperNumber(List<? extends Number> data) {
      System.out.println("data :" + data.get(0));
   }
}

Output results:

data :18
data :314

Resolution: an error will appear at (/ / 1). Because the parameter in getUperNumber() method has limited the parameter Generic upper limit to Number, the generic String is not in this range, so an error will be reported

3) . the lower limit of type wildcard is defined by the shape of list & lt;? Super Number & gt;, which means that the type can only accept Number and its three-tier parent class types, such as instances of Object type.

Last article: aggregate
Next article: serialize

If you are interested in the content of the course, you can scan the code to pay attention to our official account or QQ group, and pay attention to our curriculum updates in time.


Posted by cocpg on Sat, 07 Mar 2020 17:29:51 -0800