{"id":481,"date":"2019-06-30T15:18:03","date_gmt":"2019-06-30T22:18:03","guid":{"rendered":"http:\/\/35.243.195.209\/?p=481"},"modified":"2020-04-11T22:46:49","modified_gmt":"2020-04-12T05:46:49","slug":"generics-in-java-compared-to-c-templates","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/06\/30\/generics-in-java-compared-to-c-templates\/","title":{"rendered":"Generics in Java Compared to C++ Templates"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>In this post, I will introduce <a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/extra\/generics\/\">Generic<\/a> in Java. The post may be useful when you are working with Java with prior knowledge of C++.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Context<\/h2>\n\n\n\n<p>The context is that I want to define an <code>AbstractBaseClass<\/code> which is a top-level abstract class but different subclasses require different types of arguments for some member functions.<\/p>\n\n\n\n<p>With the knowledge of C++, we know that things can be done through class template and specialization (refer to <a href=\"http:\/\/35.243.195.209\/index.php\/2019\/05\/04\/class-template-definition-and-declaration\/\">my another post<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>As usual, we provide the conclusion first.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Java is not truly Generic as C++ is. Java pretends to be generic leveraging Java compiler.<\/li><li>In Java, there is no concept of specialization, but we can use inherence to implement specialization.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">\/\/ Base.java\npublic class Base&lt;T> {\n    public abstract void foo(T a);\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">\/\/ Derived.java\npublic class StringDerived extends Base&lt;String> {\n    public abstract void foo(String a) {\n        System.out.println(a);\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Details<\/h2>\n\n\n\n<p>Let&#8217;s dive deeper to see what happens in Java&#8217;s Generics.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Type Erasure<\/h3>\n\n\n\n<p>The Type Erasure is the main technique under Java&#8217;s Generics. The main characteristic of the technique is the elimination of the parameterization types during source-code translation to JVM bytecodes. See the codes below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">Vector&lt;Integer> iv = new Vector&lt;Integer>();\nVector&lt;String>  sv = new Vector&lt;String>();\n\n\/\/ correct\niv.add(new Integer(1));\nsv.add(new String(\"abc\"));\nInteger ival = iv.get(0);\nString  sval = sv.get(0);\n\n\/\/ illegal, could not compile\nsv.add(new Integer(1));\niv.add(new String(\"abc\"));<\/code><\/pre>\n\n\n\n<p>It will be translated into the following codes by Java Generics compiler.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">Vector iv = new Vector();\nVector sv = new Vector();\n\niv.add(new Integer(1));\nsv.add(new String(\"abc\"));\n\nInteger ival = (Integer) iv.get(0);\nString  sval = (String) sv.get(0);<\/code><\/pre>\n\n\n\n<p>We found that all instantiations of the parameterized class <code>Vector&lt;&gt;<\/code> are replaced with its nongeneric alternative <code>Vector<\/code>.<\/p>\n\n\n\n<p>The good thing is the compiler helps programmers to do the type checks and casts. And the compiler finishes them better and safer. And all parameterized types share the same class or interface at runtime.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Is Instance<\/h3>\n\n\n\n<p>Consider the following codes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ C++\nbool test() {\n    vector&lt;int>    intv;\n    vector&lt;string> strv;\n    \/\/ return false\n    return typeid(intv) == typeid(strv);\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">boolean test() {\n\/\/ Java\n    Vector&lt;Integer> intv;\n    Vector&lt;String>  strv;\n    \/\/ return true\n    return intv.getClass()  == strv.getClass();\n}<\/code><\/pre>\n\n\n\n<p>The C++ test correctly returns false and the Java test yields true. It shows that parameterization in Java is literally &#8220;skin-deep&#8221; (or rather, compiler-deep). In C++, we know that class templates are templates that generate different classes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. &lt;T extends Base><\/h3>\n\n\n\n<p>Java Generics has a convenient &lt;T extends C> construct to restrict T parameterization only for Base-derived types. In C++, people have to implement it manually.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">template&lt;class T>\nvoid foo(T const &amp; inst) {\n    C const* test = &inst;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Limitations<\/h3>\n\n\n\n<p>There are some notable limitations in Java&#8217;s Generic.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Java Generics does not allow primitives (int, float, double, and so on) as parameterization types, though instead, people can use class Integer, Float, etc.<\/li><li>Java Generics does not allow specialization of a generic class.<\/li><li>Java Generics does not have run-time type information for parameterized types. Since those types do not exist beyond the source code, which makes things complicated. See the codes below.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">\/\/ not valid in Java\nclass Allocator&lt;T> {\n    public T allocate() { \n        return new T(); \n    }\n}\n\/\/ \/\/ not valid in Java\nclass Foo&lt;T> {\n    public void foo(T inst) {\n        inst.do_something();\n    }\n}<\/code><\/pre>\n\n\n\n<p>To achieve this, you have to use a Factory model for the Allocator example and impose unnecessary polymorphism in the Foo example (like implement a specialized subclass).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reference<\/h2>\n\n\n\n<p><a href=\"http:\/\/www.drdobbs.com\/java-generics-and-c-templates\/184401818\">This Post at Dr.Dobb&#8217;s<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, I will introduce Generic in Java. The post may be useful when you are working with Java with prior knowledge of C++. Context The context is that I want to define an AbstractBaseClass which is a top-level abstract class but different subclasses require different types of arguments for some member functions&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,33,59,5,25],"tags":[],"class_list":["post-481","post","type-post","status-publish","format-standard","hentry","category-c","category-java","category-ood","category-proglang","category-software-engineering"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=481"}],"version-history":[{"count":5,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/481\/revisions"}],"predecessor-version":[{"id":957,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/481\/revisions\/957"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}