C++ Programmers Learn Java Series 34: Generics

Posted by sak on Mon, 10 Jun 2019 20:43:46 +0200

Suppose we have a requirement to write a sort method that can sort integer arrays, string arrays, or even any other type of arrays. How can we do that?

The answer is: Java generics.

generic method

You can write a generic method that receives different types of parameters when invoked. Depending on the type of parameters passed to generic methods, the compiler handles each method call appropriately.

Here are the rules for defining generic methods:

  • 1) All generic method declarations have a type parameter declaration section (separated by angle brackets) that precedes the method return type (in the following example, <E>).
  • 2) Each type parameter declaration contains one or more type parameters separated by commas. A generic parameter, also known as a type variable, is an identifier used to specify the name of a generic type.
  • 3) Type parameters can be used to declare return value types, and can be used as placeholders for actual parameter types obtained by generic methods.
  • 4) The declaration of generic method bodies is the same as that of other methods. Note that type parameters can only represent reference types, not primitive types (such as int,double,char, etc.).

Example

public class JavaTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Integer[] intArray = { 1, 2, 3, 4, 5 };
		Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
		Character[] charArray = { 'A', 'B', 'C' };

		printArray(intArray);
		printArray(doubleArray);
		printArray(charArray);
		
		System.out.println(maximum(1,2,3));
		System.out.println(maximum(1.1,2.2,3.3));
		System.out.println(maximum("bbb","ccc","aaa"));
	}

	public static <E> void printArray(E[] inputArray) {

		for (E element : inputArray) {
			System.out.printf("%s ", element);
		}
		System.out.println();
	}
        //Bounded type parameters
	public static <T extends Comparable<T>> T maximum(T x, T y, T z) {

		T max = x;
		if (y.compareTo(max) > 0) {
			max = y;
		}

		if (z.compareTo(max) > 0) {
			max = z;
		}

		return max;
	}
}
Output:
1 2 3 4 5 
1.1 2.2 3.3 4.4 
A B C 
3
3.3
ccc

generic class

The declaration of generic classes is similar to that of non-generic classes except that the type parameter declaration section is added after the class name.

Like 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 used to specify the name of a generic type. Because they accept one or more parameters, these classes are called parameterized classes or parameterized types.

Example

public class Test<T> {

	private T t;
	
	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	
		Test<Integer> integerTest = new Test<Integer>();
		Test<String> stringTest = new Test<String>();
		
		integerTest.setT(new Integer(10));
		stringTest.setT(new String("Hello"));
		
		System.out.printf("Int: %d\n\n", integerTest.getT());
		System.out.printf("Str: %s\n\n", stringTest.getT());
	}
}
Output:
Int: 10

Str: Hello

wildcard

1. Type wildcards are generally used instead of specific type parameters.

For example, List<?> is logically the parent class of List<String>, List<Integer> and all List<Specific Type Arguments>.

Example

import java.util.ArrayList;
import java.util.List;

public class JavaTest<T> {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		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);
		
		System.out.println("------------------Partition line------------------------");
		
		

		//getUperNumber(name); // parameter type error
		getUperNumber(age);
		getUperNumber(number);
		
		//getSuperNumber(name); // parameter type error
		//getSuperNumber(age); // parameter type error
		getSuperNumber(number);
		
	}
	
	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));
	}
	
	public static void getSuperNumber(List<? super Number> data){
		System.out.println("data:" + data.get(0));
	}
}
Be careful:

1) Because the parameter of getDate() method is List type, name, age and number can be used as arguments of this method, which is the function of wildcards.

2) Type wildcard upper limits are defined by the form List

     List<? Extds Number > data indicates that wildcard generic values can only accept Number and its underlying subclass types.

List <? Super Number > data indicates that type wildcard generic values can only accept Number and its upper parent type.



Topics: Java