Java generic learning examples

  • 2020-04-01 03:20:26
  • OfStack

Java Generics is a new feature introduced in JDK5 that allows the use of Type parameters when defining classes and interfaces. The declared type parameter is replaced with a specific type when used. Now the main application of generics is in the new collection class framework in JDK5. Map and List are both useful. The advantages are obvious, we can extend more classes horizontally, but the disadvantages are actually his advantages, because it requires us to be clear about the purpose of our code when using generic classes, and not to use wrong types.

The most basic generic class


package com.garinzhang.javabase.generic.e1;
/**
*  The most basic generic class, the type is defined by itself 
* @author Garin Zhang
*
* @param <T>
*/
public class Point<T> {
private T var;
public T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
}
package com.garinzhang.javabase.generic.e1;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Point<String> p = new Point<String> ();
p.setVar("coder");
System.out.println(p.getVar());
}
}

Multiple generic types


package com.garinzhang.javabase.generic.e2;
/**
*  Multiple generic types, often preferably close T Of letters such as S,R Etc. 
* @author Garin Zhang
*
* @param <T>
* @param <S>
*/
public class Notepad<T, S> {
private T key;
private S value;
public T getKey() {
return this.key;
}
public S getValue() {
return this.value;
}
public void setKey(T key) {
this.key = key;
}
public void setValue(S value) {
this.value = value;
}
}
package com.garinzhang.javabase.generic.e2;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Notepad<String, Integer> p = new Notepad<String, Integer> ();
p.setKey("coder");
p.setValue(99999);
System.out.println("key: " + p.getKey());
System.out.println("value: " + p.getValue());
}
}

Use the wildcard "?" in method parameters


package com.garinzhang.javabase.generic.e3;
/**
*  The key to this example is main In the method 
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e3;
/**
*  Use wildcards in method parameters 
* @author Garin Zhang
*
*/
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i = new Info<String>();
i.setKey("coder");
fun(i);
Info<Integer> j = new Info<Integer>();
j.setKey(9999);
fun(j);
}
public static void fun(Info<?> temp) {
System.out.println("Content: " + temp);
}
}

Failure of upward transition


package com.garinzhang.javabase.generic.e4;
/**
*  The key to this example is main In the method 
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e4;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
Info<Object> objEg;
//Type mismatch: unable to convert from Info<String> The to Info<Object>"
//Failure to turn up, String -> The Object
// objEg = strEg;
}
}


The use of generics in interfaces


package com.garinzhang.javabase.generic.e5;
/**
*  The key to this example is main In the method 
* @author Garin Zhang
*
* @param <T>
*/
interface Info<T> {
public T getVar();
}
package com.garinzhang.javabase.generic.e5;
/**
*  A generic class 
* @author Garin Zhang
*
* @param <T>
*/
public class InfoImpl<T> implements Info<T> {
private T var;
public InfoImpl(T var) {
this.setVar(var);
}
public void setVar(T var) {
this.var = var;
}
public T getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
/**
*  A generic class 
* @author Garin Zhang
*
* @param <T>
*/
public class InfoImpl1 implements Info<String> {
private String var;
public InfoImpl1(String var) {
this.setVar(var);
}
public void setVar(String var) {
this.var = var;
}
public String getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new InfoImpl<String>("coder");
System.out.println("Content: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("coder1");
System.out.println("Content: " + strEg1.getVar());
}
}

Wildcards and the use of extends, super


package com.garinzhang.javabase.generic.e6;
/**
*  The key to this example is main In the method 
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e6;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
strEg.setKey("coder");
//"The method fun(Info<? Extends Number>) In the type GenericExample is not applicable for the arguments (Info<String>) "
// upTypeLimit(i);
//Integer, Number, whatever
Info<Integer> intEg = new Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
//Compile error "The method downTypeLimit(Info<? Super String>) In the type GenericExample is not applicable for the arguments (Info<Integer>) "
// downTypeLimit(intEg);
 
//Because it USES super, downTypeLimit can only accept strings themselves and objects
//We looked at the inheritance of String, no other classes, just Object
downTypeLimit(strEg);
 
Info<Object> objEg = new Info<Object>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* <? extends T>  Represents the upper bound of a type, and the possibility of a parameterized type is T  or  T A subclass of 
* @param temp
*/
public static void upTypeLimit(Info<? extends Number> temp) {
System.out.println("Content: " + temp);
}
 
/**
* <? super T>  Represents the lower bound of the type ( Java Core Is called a supertype qualifier), indicating that the parameterized type is a supertype (parent type) of this type, up to and including Object
*  In this case, denotes T Only for Object or String Because the String Only inheritance in Object
* @param temp
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("Content: " + temp);
}
}

 

Method generics, multiple generics in a method


package com.garinzhang.javabase.generic.e7;
/**
*  Method generics, multiple generics in a method 
* @author Garin Zhang
*
* @param <T>
*/
public class Info {
/**
*  Format: method modifier  < A comma-separated list of types > Returns the method name of the value type ( The list of parameters )
*  Such as: public <T, S> T fun(T t, S s)
* @param t
* @param s
* @return
*/
public <T, S> T fun(T t, S s) {
System.out.println(s.toString());
return t;
}
}
package com.garinzhang.javabase.generic.e7;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info info = new Info();
String str = info.fun("coder", "print second generic param");
System.out.println(str);
 
int i = info.fun(30, "print second param again");
System.out.println(i);
}
}

The generic type passed in or returned from a method is determined by the type of parameter set when the method is called


package com.garinzhang.javabase.generic.e8;
/**
* extends
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T extends Number> {
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e8;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); //Here the type has been determined to be Integer
System.out.println(intEg.getVar());
}
/**
*  The generic type passed in or returned from a method is determined by the type of parameter set when the method is called 
* @param param
* @return
*/
public static <T extends Number> Info<T> fun(T param) {
Info<T> temp = new Info<T>();
temp.setVar(param);
return temp;
}
}

Make the two parameter types passed into the method consistent


package com.garinzhang.javabase.generic.e9;
/**
*  To view main
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e9;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i1 = new Info<String>();
i1.setVar("Hello");
 
Info<String> i2 = new Info<String>();
i2.setVar("Coder");
 
Info<Integer> i3 = new Info<Integer>();
i3.setVar(999);
 
add(i1, i2);
 
//Compilation error "The method add(Info<T> Info<T>) In the type GenericExample is not applicable for the arguments (Info<String> Info<Integer>) "
// add(i1, i3);
}
/**
*  The two parameter types passed into the method must be consistent 
* @param param
* @return
*/
public static <T> void add(Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}

Generics, mutable Arguments, similar to the Arguments object in javascript


package com.garinzhang.javabase.generic.e10;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Integer i[] = fun(1, 2, 3, 4, 5, 6);
fun2(i);
}
public static <T> T[] fun(T... arg) {
return arg;
}
public static <T> void fun2(T param[]) {
System.out.println("generic array: ");
for(T t : param) {
System.out.println(t + " ,");
}
}
}


Generic nesting: use generic classes as arguments; The return value is determined by the return value type

package com.garinzhang.javabase.generic.e11;
/**
*  Accept two generic types 
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T, V> {
private T var;
private V value;
 
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
 
public V getValue(){
return this.value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e11;
/**
*  accept 1 Generic types 
* @author Garin Zhang
*
* @param <T>
*/
public class Demo<S> {
private S info;
public Demo(S info) {
this.setInfo(info);
}
public void setInfo(S info) {
this.info = info;
}
public S getInfo() {
return this.info;
}
}
package com.garinzhang.javabase.generic.e11;
import java.util.List;
import com.google.common.collect.Lists;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
Info<String, Integer> i;
i = new Info<String, Integer>();
i.setVar("Coder");
i.setValue(999);
d = new Demo<Info<String,Integer>>(i);
System.out.println("Content: " + d.getInfo().getVar());
System.out.println("Content: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
//Warning "Type safety: A generic array of Object&Comparable<?> &Serializable is created for a varargs parameter"
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I ", "am ", "a ", "coder").toString());// [I , am , a , coder]
 
List<String> list = Lists.newArrayList("I ", "am ", "a ", "coder");
System.out.println(list.toString()); // [I , am , a , coder]
}
/**
*  The generic type is determined by the return value, which is automatically generated by the method's definition 
* @param elements
* @return
*/
public static <E> List<E> query(E... elements) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
// import com.google.common.collect.Lists;
// <dependency>
// <groupId>com.google.guava</groupId>
// <artifactId>guava</artifactId>
// <version>16.0.1</version>
// </dependency>
return Lists.newArrayList(elements);
}
}


Related articles: