1. Simple understanding of generics
Generics are a new feature of Java SE 1.5. The essence of generics is a parameterized type, which means that the data type being operated on is specified as a parameter. The popular point is "type variable". Variables of this type can be used in the creation of classes, interfaces and methods.
The easiest way to understand Java generics is to think of them as a convenience syntax that saves you some Java casting operations:
Copy the code as follows: List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);
The above code itself expresses itself very clearly: box is a List containing Apple objects. The get method returns an Apple object instance, and no type conversion is required in this process. Without generics, the above code needs to be written like this:
Copy the code as follows: Apple apple = (Apple)box.get(0);
2. The embarrassment of generics
The biggest advantage of generics is that it provides program type safety and is backward compatible, but it also has an awkward point, which is that the type of the generic must be specified every time it is defined. Not only does it feel a bit verbose to explicitly specify it, but it is also a lot of Programmers are not familiar with generics, so they are often unable to provide correct type parameters. Now the compiler can automatically infer the parameter types of generics, which can reduce such situations and improve code readability.
3. Improvements in generic type inference in Java 7
In previous versions, when using generic types, you need to add the generic type on both sides when declaring and assigning values. For example:
Copy the code as follows: Map<String, String> myMap = new HashMap<String, String>();
You may think: I have already specified the parameter type when declaring the variable, why do I need to specify it again when initializing the object? Fortunately, in Java SE 7, this method has been improved, and now you can declare and assign values using the following statements:
Copy the code as follows: Map<String, String> myMap = new HashMap<>(); //Pay attention to the "<>" at the end
In this statement, the compiler will automatically infer the generic type when instantiating HashMap based on the generic type when the variable is declared. Again, be sure to pay attention to the "<>" after new HashMap. Only adding this "<>" means automatic type inference. Otherwise, it is a non-generic type HashMap, and it will be given when using the compiler to compile the source code. A warning note.
However: Java SE 7's type inference when creating generic instances is limited: only if the parameterized type of the constructor is explicitly declared in the context, type inference can be used, otherwise it will not work. For example: The following example cannot be compiled correctly in Java 7 (but it can be compiled in Java 8 now, because the type of the generic is automatically inferred based on the method parameters):
Copy the code code as follows:
List<String> list = new ArrayList<>();
list.add("A");// Since addAll expects a parameter of type Collection<? extends String>, the following statement cannot pass
list.addAll(new ArrayList<>());
4. Improvements in generic type inference in Java 8
There are two main types of target type inference for generics in Java 8:
1. Support inferring generic target types through method context
2. Supports passing generic type inference to the last method in the method call chain.
Let’s look at an example from the official website:
Copy the code code as follows:
class List<E> {
static <Z> List<Z> nil() { ... };
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E head() { ... }
}
According to the characteristics of JEP101, we can write like this when calling the above method
Copy the code code as follows:
//Automatically infer the type of the generic through the target parameter of the method assignment
List<String> l = List.nil();
//Instead of the specified type displayed
//List<String> l = List.<String>nil();
//Infer the type of the generic through the previous method parameter type
List.cons(42, List.nil());
//Instead of the specified type displayed
//List.cons(42, List.<Integer>nil());
5. Summary
The above is the feature content of JEP101. As a representative of static languages, Java can be said to have a rich type system. The problem of converting between types troubles every Java programmer. Automatically inferring types through the compiler can slightly alleviate the problem of too complex type conversion. Although it is a small improvement, it will definitely have a huge impact on our programmers who write code every day. At least they will feel happier ~~ Maybe in Java 9, we will get a universal type var, like js or Some dynamic languages of scala are like that^_^