New Year’s Message: 2020 will finally pass, 2021 through the thorns

1 Why generics?

Since the Java 5 before, there is no generic this concept, from the collection to read each object must be transformed, when you insert the wrong type of object, will go wrong at run time. At run time to get the result is poor performance, so it is very important generic, it will run-time error at compile time, Make our program run as expected, reduce the occurrence of errors.

The term sample
Parameterized type List<String>
Actual type parameter String
The generic List<E>
Formal type parameter E
Unrestricted wildcard List<?>
Protoecological type List
Recursive sort type < T extends Comparable<T>>
Restricted wildcards (upper limit) List<? extend Number>
Restricted wildcards (lower limit) List<? super Number>
The generic type String.class
Generic method static <T> T[] toArray(T[],Object t)

Do not use the original ecological type

//List
       
        
       
      

public static void main(String[] args) {

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

   unsaveAdd(strList,Integer.valueOf(11));

   String result = strList.get(0);

}



private static void unsaveAdd(List list, Object obj){

    list.add(obj);

}

Java.lang.Integer cannot be cast to java.lang.String

// Let's make it better with generics

private static void unsaveAdd(List<String> list, Object obj){

    list.add(obj);

}

Add (java.lang.string)in list cannot be appliedto(java.lang.object)

Copy the code

Class, String[]. Class, int. Class, but not with generics, such as List<String. Class >, List<? >.class

Eliminate non-inspection warning

If it is impossible to eliminate warnings while ensuring that the type of code that proves the warning is secure, we can eliminate warnings via @SuppressWarnings(“unchecked”).

// toArray method in ArrayList class

// Compile-time warning

public <T> T[] toArray(T[] a) {

  if (a.length <size) {

    return (T[]) Arrays.copyOf(elements,size,a.getClass());

  }

  if (a.length >size) {

      a[size] = null;

  }

}

// the above arrays.copyof () method generates warnings, as long as you're sure the type of code proving the warnings is safe

public Object[] toArray() {

    return Arrays.copyOf(elementData, size);

}

@SuppressWarnings("unchecked")

public static <T> T[] copyOf(T[] original, int newLength) {

      return (T[]) copyOf(original, newLength, original.getClass());

}

Copy the code

Generic lists are preferred over arrays

Arrays are typed at run time, generic lists are typed at compile time and erased at run time

Object[] obj = new Long[1];

obj[0] = "Hello World";//Throws ArrayStoreException



List<Object> list = new ArrayList<long> ();//Incompatible types

list.add(Hello World);



// When comparing the two implementations above, it is clear that the list approach takes precedence over the array approach, regardless of the error location and time

Copy the code

5. Give priority to generics and generic methods

// Unchecked error version

public static void main(String[] args) {

    Set s1 = new HashSet();

    s1.add("Braised chicken");

    Set s2  = new HashSet();

    s2.add("Fish with pickled cabbage");

    System.out.println(Food.eatAll(s1,s2));

}

public static Set eatAll(Set s1, Set s2){

    Set result = s1;

    result.addAll(s2);

    return result;

}

// Generic version

public static void main(String[] args) {

    Set<String> food1 = new HashSet<>();

    food1.add("Braised chicken");

    Set<String> food2 = new HashSet<>();

    food2.add("Fish with pickled cabbage");

    System.out.println(Food.eatAll(food1, food2));

}



private static <E> Set eatAll(Set<E> s1, Set<E> s2) {

    Set<E> set = new HashSet<>(s1);

    set.addAll(s2);

    return set;

}

Copy the code

For the last two versions of the code, using generics will result in an array of Unchecked prompts (Unchecked call to ‘addAll(Collection<? Extends E>)’ as a member of raw type ‘java.util.set’), idea interface has no hint after using generics. Generics help us avoid exception problems at compile time.

Improve API flexibility with limited wildcards

Rewrite the code above to show the flexibility of finite wildcards, often used on method parameters

public static void main(String[] args) {

    System.out.println();

    Set<Integer> first = new HashSet<>();

    first.add(1);

    Set<Long> two = new HashSet<>();

    two.add(2L);

    Set<Number> result = Food.union(first,two);

    System.out.println(result);

}

public static <E> Set union(Set<? extends E> s1, Set<? extends E> s2) {

    Set<E> result = new HashSet<>(s1);

    result.addAll(s2);

    return result;

}

Copy the code

means that the upper limit is E, depending on the input parameter. Set result = Food. Union (first,two) means that the maximum type is Number, and subtypes of Number can be accepted, such as Long,Integer….. Subtypes, wildcards can greatly increase the flexibility of an API.

That’s all there is to know about Java generics. If it’s helpful, please like it, follow it, and retweet it

References:

[1] Effective Java