Improvements to the generic target type inference method in Java8

  • 2020-04-01 03:22:10
  • OfStack

I. simple understanding of generics

Generics, a new feature of Java SE 1.5, are essentially parameterized types, meaning that the data type being manipulated is specified as a parameter. The colloquial term would be "variables of type". This type of variable can be used in the creation of classes, interfaces, and methods.

The easiest way to understand Java generics is to think of it as a convenient syntax that saves you some operations on Java type conversion (casting) :

List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);

The above code itself makes it clear: box is a List of Apple objects. The get method returns an instance of an Apple object, which does not require a cast. Without generics, the code above should look like this:
Apple apple = (Apple)box.get(0);

The awkwardness of generics

The biggest advantage of the generic type is the type of security at the same time provides the program can be backward compatibility, but there are also embarrassed, every time is defined to specify a generic type, such specified feels a bit tedious, not only the most main is a lot of programmers are not familiar with generics, so most of the time will not be able to give the correct type parameters, now automatically by the compiler infer generic parameter type, can reduce the situation, and improve code readability.


Third, java7 generic type inference improvements

Using generic types in previous versions required adding generic types to both sides of the declaration and assignment. Such as:

Map<String, String> myMap = new HashMap<String, String>();

You might think: lao-tzu has specified the parameter type when declaring the variable, but not before initializing the object? Fortunately, in Java SE 7, this approach has been improved so that you can now declare and assign values using the following statement:
Map<String, String> myMap = new HashMap<>(); // Notice the back "<>"

In this statement, the compiler automatically infers the generic type for instantiating a HashMap based on the generic type at the time the variable was declared. Again, be sure to note the "<" after the new HashMap. >" , just add this "< >" This represents automatic type inference, otherwise it is a HashMap for non-generic types and gives a warning when the source code is compiled using the compiler.

However, Java SE 7 has a limitation on type inference when creating generic instances: type inference cannot be used unless the constructor's parameterized type is explicitly declared in the context. For example, the following example did not compile correctly in Java 7 (but it now compiles in Java 8 because the type of a generic type is automatically inferred based on method parameters) :


List<String> list = new ArrayList<>();
list.add("A");//Because addAll expects to get Collection<? Extends String> Type, so the following statement cannot be passed
list.addAll(new ArrayList<>());


Iv. Java8 generic type inference improvements

There are two main types of generic target type inference in java8:

1. Support for inferring generic target types from method context
2. Support for generic type inference to be passed to the last method in the method invocation link
Let's take a look at the official website:


class List<E> {
   static <Z> List<Z> nil() { ... };
   static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
   E head() { ... }
}

  According to the JEP101 feature, we can write this when we call the above method


//The type of the generic is automatically inferred by the target parameter assigned by the method
List<String> l = List.nil();
//Instead of the specified type shown
//List<String> l = List.<String>nil();
//Infer the type of the generic from the previous method parameter type
List.cons(42, List.nil());
//Instead of the specified type shown
//List.cons(42, List.<Integer>nil());

Five, the summary

Those are the features of JEP101, the type system that Java represents as a static language is quite rich. The problem of converting types to each other is a problem that plagues every Java programmer, and the compiler's ability to automatically infer what types are is a small relief. It's a small step, but it's certainly going to make a huge difference to our everyday programmers, at least in a better mood ~~ maybe in Java 9 we'll get a generic type called var, like js or some of scala's dynamic languages


Related articles: