A brief introduction to generics of Java Basics

1. What is java generics?

java generics: the English name is generics. Generics is a new feature introduced by jdk5. The essence of java generics is parameterized types, that is, all operation data types are specified as a parameter. Entities that operate on parameterized types, such as classes, interfaces, or methods, are called generic entities.

2. java generic class

Generic class: must be declared before use; The declaration is through < T, E,... > Achieved; Convention generics can be represented by a single uppercase letter T, E, K, V, and so on

import java.lang.reflect.Field;

public class GenericsSimpleExample {

    public static void main(String[] args) {
        A<String , Integer> a0 = new A<>();
        a0.t= "testStr";
        A<Integer , Integer> a1 = new A<>();
        a1.t = 100;
         //  Generic parameters should refer to data types when used, not basic data types, such as int, etc
        //A<Integer , int> a2 = new A<>();

        // If a generic class does not specify a specific parameter type, the default data type is object
        Class<A> cls = A.class;
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName() + ":" + field.getType().getSimpleName());
        }

        // Different data types can be seen in the specific implementation of generic classes. In practice, they are the same data types, which can be verified by hashcode
        System.out.println(a0.getClass().hashCode());
        System.out.println(a1.getClass().hashCode());
    }

    static class A <T , E> {
        public T t;
        public void test0(T  t) {

        }
    }

}

Key points:

  • The parameter type of a generic class cannot be a basic data type. Use a reference data type
  • When a generic class does not specify a specific data type, it uses the object type by default
  • Generic classes can use different data types, which are actually the same data types

3. Subclasses derived from generic classes

  • 1. If the subclass is generic, the subclass should be consistent with the generic type of the parent class
class A<T> extends B<T>{}
  • 2. If the subclass is not generic, the parent class should specify the generic data type
class A extends  B<String>{}

4. Generic interface

Generic interface syntax:

interface Interface name <Generic identity,Generic identity, ...>{
  Generic identity method name();
  ...
}
  • 1. The implementation class is also a generic class, and the generic type should be consistent with the interface
interface B <T,V> {}
class A<T,V> implements B<T,V>{}
  • 2. The implementation class is not a generic class, and the interface should specify a specific type
class B implements B<String,Integer>{}

5. Generic method

Generic method syntax:

Modifier  <T,E,...> Return value type method name (parameter list ){
  Method body;
}

Generic method characteristics:

  • Only the method that declares < T > is a generic method. Only the generic method used for parameter passing is not a generic method
  • Like generic classes, you can use K, V, T, E, and so on to represent generics
public class GenericsMethodExample {

    public static void main(String[] args) {
        A0 a0 = new A0();
        a0.test0("hello");

        A1<Integer> a1 = new A1<>();
        a1.test("hi", "hello");
        A1.test1("hello world");

    }

    static class A0 {
        public <T, E> T test0(T t) {
            System.out.println("t = " + t);
            return null;
        }
    }

    static class A1<K> {

        /**
         * When the type of generic method is consistent with that of generic class, the of specific method shall prevail
         * @param k
         * @param t
         */
        public <T, K> T test(T t , K k) {
            System.out.println("t = " + t);
            System.out.println("k = " + k);
            return null;
        }

        /**
         * static Method must be specified as a generic method plus {@ code < k >}
         * @param k
         */
        public static <K> void test1(K k) {

        }
    }
}

induce:

  • When the type of generic method is consistent with that of generic class, the of specific method shall prevail
  • To use generics for static methods, you must specify a generic method plus

6. Generic wildcard

Type wildcards are generally used? Instead of specific type arguments, type wildcards are type arguments, not type parameters

public class GenericsWildcardExample {

    public static void main(String[] args) {
        A<String> a0 = new A<>();
        show(a0);

        A<Integer> a1 = new A<>();
        show(a1);

    }

    public static void show(A<?> a){
        System.out.println(a.getClass());
    }

    static class A<T> {

    }
}

7. Type wildcard upper limit

Syntax:

class/Interface <? extends actual argument >

It is required that the modified generic type can only be an argument type or a subclass type of an argument

  public class GenericsWildcardExample {

    public static void main(String[] args) {
 
        A<A1> a11 = new A<>();
        A<A2> a12 = new A<>();
        A<A3> a13 = new A<>();

        // Only A2 and its subclasses can be used
        show0(a12);
        show0(a13);
    }

    public static void show0(A<? extends A2> a) {}

    static class A<T> {

    }

    static class A1{}

    static class A2 extends A1{}

    static class A3 extends A2{}
}

8. Type wildcard lower limit

Syntax:

class/Interface <? super actual argument >

It is required that the modified generic type can only be the argument type or the parent type of the argument

public class GenericsWildcardExample {

    public static void main(String[] args) {

        A<A1> a11 = new A<>();
        A<A2> a12 = new A<>();
        A<A3> a13 = new A<>();

        // Only A2 and its parent classes can be used
        show1(a11);
        show1(a12);

    }

    public static void show1(A<? super A2> a){}

    static class A<T> {

    }

    static class A1{}

    static class A2 extends A1{}

    static class A3 extends A2{}
}

9. What is generic erasure?

Generic information only exists in the code compilation stage. Before entering the JVM, the information related to generics will be erased
Drop, we call it type erase

9.1 unlimited type erasure

import java.lang.reflect.Field;


public class GenericsWipeExample {

    public static void main(String[] args) {
        Class<?> cls0 = A.class;
        Field[] fields = cls0.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName() + ":" + field.getType().getSimpleName());
        }

    }


    static class A <T>{
        T t;
    }
}

Print:

t:Object

9.2 limited type erasure

import java.lang.reflect.Field;


public class GenericsWipeExample {

    public static void main(String[] args) {
 

        Class<?> cls1 = A1.class;
        Field[] fields1 = cls1.getDeclaredFields();
        for (Field field : fields1) {
            System.out.println(field.getName() + ":" + field.getType().getSimpleName());
        }

    }

    static  class A1<T extends Number> {
        T t;
    }

}

Print:

t:Number

9.3 method type

import java.lang.reflect.Method;

public class GenericsWipeExample {

    public static void main(String[] args) {
      

        Class<?> cls2 = A2.class;
        Method[] methods = cls2.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName());
        }
    }

    static class A2<T extends Number> {
        T t;
        public <K extends Number> K test(K k) {
            return null;
        }
    }

}

Print

test:Number

9.4 bridging method

interface MyInter<T>{
  T fun1();
}
class DD implements MyInter<String>{
  @Override
  public String fun1() {
    return null;
 }
}
import java.lang.reflect.Method;


public class GenericsWipeExample {

    public static void main(String[] args) {
   
        Class<?> cls3 = A3.class;
        Method[] methodss = cls3.getDeclaredMethods();
        for (Method method : methodss) {
            System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName());
        }
    }

    interface MyInter<T>{
        T test();
    }
    class A3 implements MyInter<String> {
        @Override
        public String test() {
            return null;
        }
    }

}

Print:

test:String
test:Object

10. Generics and reflection

 Class<?> cls0 = A.class;
Field[] fields = cls0.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.getName() + ":" + field.getType().getSimpleName());
}

Keywords: Java Class interface reflection

Added by Rottingham on Sun, 26 Dec 2021 11:10:41 +0200