C + + generics && Java Generic Implementation mechanism

Source: Internet
Author: User

C + + generics
C + + generics are different from the run-time polymorphic mechanism of virtual functions, the static polymorphism supported by generics, when the type information is available, the maximum efficiency and flexibility can be obtained by using the compile-time polymorphism. When the specific type information is not available, it is necessary to resort to the run-time polymorphism, that is, the dynamic polymorphism supported by the virtual function.

For C + + generics, each of the actual types that have been identified has a separate encoding to produce, that list<int> list<string> is, different code is generated, and the compiler ensures type safety at this point. Because the exact type of object is known, the compiler does not use RTTI when it generates code, which makes the efficiency of generics as high as manual coding.
It is obvious that this approach increases the code space, which is a space-time change compared to runtime polymorphism.

Java generics
When the compiler compiles Java code with generics, it performs type checking and type inference, and then generates normal, non-generic bytecode that can be received and executed by a generic Java virtual machine, known as erasure (Erasure).

It is visible that the compiler can use generic type information to ensure type safety while compiling the source program (Java code with generics), while erasing the type information in the resulting bytecode.
As defined in the code List<object> and the List<String> type, after compilation will be programmed list. The JVM sees only the list, and the type information appended by generics is not visible to the JVM. The Java compiler will try to identify possible errors at compile time, but there is still no way to avoid a type conversion exception at run time.

Erase principle:
1) All parameterized container classes are erased into non-parameterized (raw type), such as List<E>、List<List<E> > are erased to list;
2) All parameterized arrays are erased into a non-parameterized array; List<E>[] List[]
3) The container class of Raw type is erased to itself, such as list is erased to list;
4) native types (int,string and wrapper classes) are erased to their own;
5) parameter type E, erased into object;
6) All constraint parameters such as <? Extends E>、<X extends E> are erased into E;
7) If there are multiple constraints, erase into the first, such as <T extends Object & E> , then erase into an object;

Let's look at an example:

 Public classpair<t> { Public Pair(T first,t second) { This. first = first; This. second = second; } PublicTGetFirst() {returnFirst } PublicTGetsecond() {returnSecond } Public void Setfirst(T first) { This. first = first; } Public void Setsecond(T second) { This. second = second; }PrivateT first;PrivateT second; }

After erasing, it becomes:

 Public classPair { Public Pair(Object first,object second) { This. first = first; This. second = second; } PublicObjectGetFirst() {returnFirst } PublicObjectGetsecond() {returnSecond } Public void Setfirst(Object first) { This. first = first; } Public void Setsecond(Object second) { This. second = second; }PrivateObject first;PrivateObject second; }
publicclass QMI<T extends List> {     public Interval(T value) {         this.value = value;    }     private T value; }

After erasing:

publicclass QMI {     publicIntervalvalue) {         this.valuevalue;    }     value; }

Then, after the type erasure, how to know its true type when called, rest assured, the compiler helped us do everything, the above pair for example:
The original code is:

    Pair<String> pair = New Pair<>("","");pair.Setfirst ("Qmi");pair.Setsecond ("Kang");StringFirst= pair.GetFirst ();StringSecond= pair.Getsecond ();

Post-compilation is:

 pair  pair  =  new  pair  (, ); pair   Setfirst ( "QMI" ); pair   Setsecond ( "Kang" ); string  first =  ( String ) pair   GetFirst (); string  second =  ( String ) pair   Getsecond (); 

As you can see, the compiler helped us do the automatic type conversion.

For generics, we can use the Java single-root inheritance feature to achieve similar effects, but because the compiler does not do type checking at runtime, this check is done at run time, delaying the discovery of errors in the program.

With the generic mechanism, the compiler undertakes all types of checks to ensure the security of the type. Take List<Object> and List<String> for example to specifically analyze:

publicvoid test() {        List<String>list=new ArrayList<String>();        List.add(123//编译错误 }  

Here, an object of type integer is added to the collection declared as list. This is obviously a violation of the principle of type safety, and at some point it will definitely throw classcastexception. Therefore, the compiler prohibits such behavior. The compiler will check for possible types of security issues as much as possible. A compilation error is given where it is determined to violate the relevant principles. A warning message is given when the compiler cannot determine whether the type is being used correctly. Such mechanisms are conducive to the early detection and correction of errors.

Let me look at one more question:

publicclass QmiV<T> {    privatevalue;    publicgetValue() {        returnthis.value;    }    publicvoidsetValuevalue) {        this.valuevalue;    }}

After erasing:

public   Class  qmiv<object> {private  Object value    ; public  Object getvalue  () {return  this .    value ; } public  void   SetValue  (Object value ) {this . value  = value ; }}
//子类publicclass QmiVD extends QmiV<Person> {    @Override    public String getValue() {        returnsuper.getValue();    }    @Override    publicvoid setValue(String value) {        super.setValue(value);    }}

After erasing:

publicclass QmiVD extends QmiV<String> {    public QmiVD() {    }    public String getValue() {        return (String)super.getValue();    }    publicvoid setValue(String value) {        super.setValue(value);    }}

As you can see, for the SetValue method, the type of the parent class is object, and the subclass is of type date and the parameter type is different, so the implementation here is not an override, but an overload.
In practice, the bridge method is used to solve this problem.

The bridge method is to generate a middle layer whose parameter types are object, that is, the subclass two methods that really overwrite the parent class are two bridge methods that we cannot see. The inside of the bridge method calls the two methods we have rewritten ourselves.

Summarize:
C + + generics are very similar to Java generics, but they are fundamentally different.
First, generics in the Java language cannot accept the base type as a type parameter-it can only accept reference types. This means that it can be defined List<Integer> , but cannot be defined List<int> .
Second, in a C + + template, the compiler uses the supplied type parameters to generate different code. Generics in Java, the compiler simply erases and replaces these types of parameters. ArrayList<Integer>the types and ArrayList<String> objects share the same class, and only one ArrayList class exists.

Reference:
Https://zh.wikipedia.org/zh-cn/%E6%B3%9B%E5%9E%8B
Http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
Http://www.infoq.com/cn/articles/cf-java-generics

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

C + + generics && Java Generic Implementation mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.