Java: Generics understanding

This article is derived from reference "Think in Java", summed up many articles and blog reading source

Foreword

Java generics are using every everyone, but what is its underlying implementation method is it, so why should realize, what the advantages and disadvantages of such implementation, how to solve the problem caused by generics. With curiosity, I have access to information of a preliminary study to explore with you here.

A type parameter

Learned JAVA knows generics and understand about how to use. On the class: class class name {}, In the method: public void method name (T x) {}. Implemented into a generic type of such parameters can be passed, so that the diverse type function.

Specific divided into five cases:

  1. T is a member variable of type
  2. T is the type variable (whether member variables or local variables) of type parameters, such as common Class<T> List<T>.
  3. Method T is thrown Exception (requirement <T extends Exception>)
  4. The return value is the method of T
  5. Method T is a parameter

1.1 Generics achieve

JAVA is based on generic compiler implementation, a method of erasing implement, because it appeared after java1.5 generics compromise in order to maintain backward compatibility made.

Erase the file type is called JAVA parameter is erased when compiled into byte code, recorded separately elsewhere. And replace the original position by the parent class type parameter.
Parameter type placeholder assumed as T, erasing the following rules:

  1. <T>After erasing becomesObecjt
  2. <? extends A>After erasing becomesA
  3. <? super A>After erasing becomesObject

This rule is called the reserved upper bound

After erasing the compiler type parameter, by casting JAVA ensures proper type parameter when in use. Such as: Incoming class parameter T in the type A, then the compiler returns (throw) at the code type parameter T plus (A) for all classes A strong revolutions.

For chestnut:

        ArrayList<String> list = new ArrayList<String>();
        list.add("123");
        String b = list.get(0);

After compiling will become

        ArrayList list = new ArrayList();//没有参数即默认为Object
        list.add("123");
        String b = (String) list.get(0);

The method of forming a bridge and will ensure that the polymorphism in the subclass with class type parameter.
With particular reference to the following official explanation

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.

Two Tsuhaifu?

Within the class with the type of the parameter, the code still be processed in the parent class parameter type erased. But erasing there is a problem in this mechanism generics are the same, without the inverter and covariance.

2.1 inverter and covariant


Covariance and online there are many explanations seem vague, I give a relatively broad definition of the reference to the official explanation of several programming languages. Refers covariant type can be used (more specifically) original claim greater extent than the type of derivative, the inverter can be used means a smaller (less specific) than the original level of the derived type declared type.
Such as:
Object obj = new String("123");
This is the covariance, a String to the more specific (subclass) Object type originally assigned to the broader definition of the type (parent) of.
JAVA not allow the parent class assigned to the subclass, natural Java does not support the inverter.

Many online generic JAVA Bowen said there inverter, I do not agree, and it is just a simulation of an inverter, that is characteristic of the inverter section and looks like an inverter, the text will be given after a detailed analysis


The 2.2 Java inverter and covariance

In JAVA,

List<Integer> b = new ArrayList<Integer>()
List<NumFber> a = b;

It is not checked by the compiler. It does not allow it to have a very good reason: to do so would undermine the type of security to be generic. If it can be List<Integer>assigned List<Number>. Then the following code will allow non- Integercontent into List<Integer>:

List<Integer> b = new ArrayList<Integer>(); 
List<Number> a = b; // illegal 
a.add(new Float(3.1415));

Because ait is List<Number>, so to add Floatappears to be entirely feasible. But if aactually List<Integer>, this will undermine the implication in the btype declaration defined - it is a list of integers, which is why generic types can not change the association. But thus making generics loses expansion of polymorphism.

2.3 Wildcard solution covariant

Java official by adding a wildcard ?to solve the problem generics covariant. This will compile the:

List<Integer> b = new ArrayList<Integer>(); 
List<? extends Number> a = b;

Can be read as aa having Numbera Listset of classes, from the atime of extraction as a unified data Numberprocessing on the line. This was also in line with Richter substitution principle

However, the compiler will forbid you would like to Integerput a, that is, a.add(new Integer(1))//illegal
it is also very reasonable, because your statement ahad no defined aconcrete which contains Numbersub-categories, and therefore are not allowed to add any variables to ensure the safety of generics.
To solve the amethod is also very simple to add objects

List<Object> b = new ArrayList<Object>(); 
List<? super Number> a = b;

aIs some kind of Numberparent class Listcollections, will be ArrayList<Object>assigned ais reasonable, Objectindeed the Numberparent class. This is also in line with Richter substitution principle

(Most online Bowen said that this is the inverter, but think about the official definition of the inverter, in JAVA it can be understood as: class Tis the class Ssubclasses, and the class A<T>is a class A<S>parent class closer look List<? super Number>and List<Object>relationships, here Tis Number, and Sis Object, but List<? super Number>from a logical point of view really is List<Object>a subclass of it, if just literally List<? super Number>is with the Numbercollections of the parent class, upper bound method according to erase reserves should be erased as List<Object>the a List<Object>assigned to another List<Object>does not exist in any of the inverter. I doubt it down Google access to the information, there is no information on JAVA generic English in this part of the inverter)

Guess you like

Origin www.cnblogs.com/taojinxuan/p/11128459.html
Recommended