Java learning ==> generic

First, what is generic

  Generic, i.e. "parameterized type," is not created in the case of new type, a type parameter to control particularly limited by different types of generic specified. That is the generic use, the data type of the operation is specified as a parameter, which can be used in the type of classes, interfaces and methods, are called generic class, generic interfaces, generic method.

Two, Java in why the introduction of generics

Because inheritance and polymorphism occurs, during operation of some containers, it requires a lot of object type determination. Let's look at these two pieces of code below:

public class User {

  private Integer id;

  private String name;

  private Integer age;

  private User() {
    return;
  }

  private User(String name) {
    this();
    this.name = name;
  }

  private User(Integer id, String name) {
    this(name);
    this.id = id;
  }

  private User(Integer id, String name, Integer age) {
    this(id,name);
    this.age = age;
  }

  public static User of() {
    return new User();
  }

  public static User of(String name) {
    return new User(name);
  }

  public static User of(Integer id, String name) {
    return new User(id, name);
  }

  public static User of(Integer id, String name, Integer age) {
    return new User(id, name, age);
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "User{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            '}';
  }
}
User
public  class Demo01 { 

  public  static  void main (String [] args) { 

    List List = new new the ArrayList (); 

    // insert User object 
    list.add (User.of (1, "uncle", 40 )); 
    List.add ( User.of ( . 1, "Wood", 30 )); 

    // insert other types of objects 
    List.add (123 ); 
    List.add ( "ABB" ); 
    
    printUser (List); 
  } 

  public  static  void printUser (List List) {
     for ( int I = 0; I <list.size (); I ++ ) { 
      the User User = (User) list.get(i);
      System.out.println(user);
    }
  }
}

printUser () method of object traversing print User object, but in addition to the main method User object can be inserted, may be inserted into other types of objects, when performing the error bound. Then we have to add the following code is determined:

public static void printUser(List list) {
  for (int i = 0; i < list.size(); i++) {
    Object obj = list.get(i);
    if (obj instanceof User) {
      User user = (User) obj;
      System.out.println(user);
    }
  }
}

Write the code, then it is very troublesome, the code you need to add a lot of judgment, very inconvenient to use, so generics came into being, we just need to change the code in this form are as follows:

public  class Demo01 { 

  public  static  void main (String [] args) { 

    // used herein is generic role: list can only be installed inside the User object 
    List <User> List = new new the ArrayList <> (); 

    // Insert User object 
    list.add (User.of (1, "uncle", 40 )); 
    List.add (User.of ( . 1, "Wood", 30 ;)) 

    // if not used above generic List, here compiled no error, run-time error will
     // list.add ( "the Hello");
     // list.add ( "World"); 

    printUser (List); 
  } 

  public  static <T> void printUser (List <T> list) {
    for (int i = 0; i < list.size(); i++) {
      Object obj = list.get(i);
      System.out.println(obj);
    }
  }
}

As can be seen from the above code with generics later, we only need to specify a type when it is defined in the code of the container, then the container can only store objects of that type, there is no need in the business code determining the type of object to be simplified in a lot of code. May also be considered as a generic agreement, for convenience, a convention container only a certain type of object stored.

Third, the use of generics

Generic three different ways, namely: a generic class, generic method and generic interface.

1, a generic class

Generic class definitions for classes which can complete the opening operation of the same class of a set of generic interfaces. The most typical is a variety of containers, such as: List, Set, Map.

/ ** 
 * where K, V can easily write any identifier, such as the common K, V, T, E and other parameters commonly used in the form represents a generic 
 * when instantiating a generic class, must specify a particular type of T such as: String, Integer and so on. 
 * / 
Public  class the Generic <K, V> { 

  / ** 
   * Key, Val members of this type are variable K, V types are designated by both the external 
   * / 
  Private K Key;
   Private V Val; 

  / ** 
   * Pan shaped type class constructor parameter k and v is also a type K, V, designated by the same external 
   * / 
  public the Generic (K k, V v) {
     the this .key = k;
     the this .val = v; 
  } 

  / * * 
   * ordinary generic type of the return value K, V designated by the same external 
   * NOTE: this is not the following generic method 
   * / 
  public K getKey () {
     return  Key;
  }
  public V getVal() {
    return val;
  }
}
Generic class

However, when using a generic class will have to pass a type argument it? On the syntax is not necessarily, you can not pass, but it is best when used in accordance with the transfer agreement, otherwise we define a generic class does not make sense. If not passed, then the type of arguments, the conventional container can add any type of object, so that the type is also put in the service code determining species.

The use of generic class there is a way, and extends the use of the super keyword to limit the type we use arguments passed, as follows:

/ ** 
 * V where the extends Person Category V can only limit the use of Person and its subclasses 
 * / 
public  class the Generic <K, V the extends Person> { 
  
  Private K Key;
   Private V Val; 
  
  public the Generic (K K, V V) {
     the this .key = K;
     the this .val = V; 
  } 
  
  public K getKey () {
     return Key; 
  } 
  public V getVal () {
     return Val; 
  } 
}

2, generic interface

Definition of generic interface with generic class using substantially the same. Generic interface often used in the production of various types of vessel, may look at an example:

public interface Generic<K, V> {

  public K test01();
  public V test02();

}

When implementing generic interface class, it is passed in the generic argument:

/ ** 
 * When the generic argument passed in, and define the same generic class, the class declaration time, need to be added together with the generic class declaration 
 * namely: public class testGeneric <K, V > the generic the implements <K, V> 
 * If no generic declaration, such as: public class testGeneric implements generic, compiler error 
 * / 
public  class testGeneric <K, V> the implements the generic <K, V> { 

  @Override 
  public K Test01 ( ) {
     return  null ; 
  } 

  @Override 
  public V Test02 () {
     return  null ; 
  } 
}

When the generic interface implementation class, passing the generic argument:

/ ** 
 * When generic interface implementation classes are implemented as generic type has passed for the argument, where the use of all be replaced by a generic passed argument types 
 * / 
public  class testGeneric <String, Integer> the implements the Generic <String, Integer> { 

  @Override 
  public String Test01 () {
     return  null ; 
  } 

  @Override 
  public Integer Test02 () {
     return  null ; 
  } 
}

3, generic method

In java, the definition of a generic class is very simple, generic method is more complicated.

Generic class, is a specific type specified in the generic class instance of time. Generic method is to specify generic specific types when calling the method.

public  class the Generic <K, V> { 

  Private K K; 

  Private V V; 

  / ** 
   * generic method 
   * public of the return value of the intermediate <T> is very important, as will be appreciated this method for generic method declarations. 
   * <T> indicates that the method will use the generic type T, it can only be used at this time in the process of the generic type T. 
   * As with the definition of generic class, where T can easily write an arbitrary identifier, such as the common T, E, K, V and the like in the form of parameters used for each generic 
   * where T is as defined above generic class K and V nothing, as may, or may not be the same 
   * generic method can be defined in a generic class types may be defined in the general category among 
   * / 
  public <T> T getType (T type) {
     return type; 
  } 

  / ** 
   * static generic method 
   * / 
  public  static <S, T> the generic <S, T> of () {
     / ** 
     * type inference
     The Generic new new return * <S, T> () -> return the Generic Pair <> () 
     * / 
    return  new new the Generic <> (); 
  } 

  / ** 
   * returns the value or parameter is not generic method with a generic 
   * / 
  public K getK () {
     return K; 
  } 

  public V getv () {
     return V; 
  } 
}

Generic method enables class-independent way to produce change, if you can do it, you should try to use a generic method.

The method also supports the use of generic and super extends keyword to limit the type we use arguments passed, as follows:

public  class testGeneric { 

  public  static  void main (String [] args) { 

    Person Person = null ; 
    Str STR = null ; 
    the User User = null ; 
    
    getType (Person); 
    getType (STR); 
    // the User is not a Person or subclass, They will be given 
    getType (User); 

  } 

  / ** 
   * generic method 
   * / 
  public  static <T the extends the Person> T getType (T type) {
     return type; 
  } 
}

User is not a Person or a subclass thereof, it will be given. Str is a subclass of Person, so no error.

4, generics wildcards

Wildcards can be used as a generic reference type method, as follows:

public class App {
  public static void main(String[] args) {

    List<String> list1 = new ArrayList<>();

    list1.add("hello");
    list1.add("world");

    List<Integer> list2 = new ArrayList<>();
    list2.add(1);
    list2.add(2);

    print(list1);
    print(list2);
  }

  public static void print(List<?> list) {
    for (Object obj : list) {
      System.out.println(obj);
    }
  }
}

? Representatives can receive any type. Wildcards can also be limited by the type of the received keyword extends and super

public class App {
  public static void main(String[] args) {

    List<Person> list1 = new ArrayList<>();

    list1.add(new Person());
    list1.add(new Person());

    List<Str> list2 = new ArrayList<>();
    list2.add(new Str());
    list2.add(new Str());

    List<User> list3 = new ArrayList<>();
    list3.add(new User());
    list3.add(new User());

    print(list1);
    print(list2);
    print(list3); // 报错
  }

  public static void print(List<? extends Person> list) {
    for (Object obj : list) {
      System.out.println(obj);
    }
  }
}

Fourth, the type erasure

Generics are Java 1.5 version before the introduction of the concept, before this is not a generic concept, but generic code to be highly compatible and previous versions of the code very well, because: generic information exists only in code compilation stage , before entering the JVM, associated with the generic information is erased, erasing the type termed professional. More simply, generic class and common class in the Java virtual machine is nothing special about it. Let's look at the following code:

public class App {
  public static void main(String[] args) {
    List<Person> list1 = new ArrayList<>();
    list1.add(new Person());
    List<User> list2 = new ArrayList<>();
    list2.add(new User());

    System.out.println("list1 = " + list1.getClass());
    System.out.println("list2 = " + list2.getClass());
    System.out.println(list1.getClass() == list2.getClass());
  }
}

operation result:

Obviously, List <Person> and List <User> points in the virtual machine classes are ArrayList, generics information is erased.

When generic class types to be erased, before a generic class type parameter portion if not specified in the limit, such as <T> it would be translated into ordinary type Object, if the upper limit specified as <T extends String> the type parameters was replaced ceiling type String.

Type erasure limitations caused by:

Type erasure, it will erase a lot inherit the properties, which are the limitations it brings. Understand the type erasure in favor of bypassing the minefield we may encounter in development, the same understanding of type erasure will also allow us to bypass some of the limitations of generics itself.

Under normal circumstances, since the generic limits, the last line of code to prevent the compiler compiler, because similar mismatch. However, based on the type erasure understanding of the use of reflection, we can bypass this limitation.

public interface List<E> extends Collection<E>{
    
     boolean add(E e);
}

Source List is defined above and wherein the add () method.

Because E represents any type, so when type erasure, add method is actually equivalent to:

boolean add(Object obj);

So, using reflection, we bypass the compiler to invoke the add method

public class App {
  public static void main(String[] args) {

    List<Integer> list = new ArrayList<>();
    list.add(123);

    try {
      Method method = list.getClass().getDeclaredMethod("add", Object.class);
      method.invoke(list,"abc");
      method.invoke(list,55.5f);

    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }

    for (Object obj : list) {
      System.out.println(obj);
    }
  }
}

Operating results are:

Can be seen, according to the principle of type erasure, means using reflection bypassing the normal operating limits the development of the compiler is not allowed.

note:

  • Generic classes or generic methods are not accepted 8 basic data types;
  • You need to use their packaging;

Guess you like

Origin www.cnblogs.com/L-Test/p/11477493.html