14.4 Explain the difference between templates in C++ and generics in Java.

在Java中,泛式编程Generic Programming的实现是通过一种就做类型擦除Type Erasure的机制来实现的。当源码转为Java虚拟机JVM的字节代码时擦除参数的类型,例如下面的例子:

Vector<String> vector = new Vector<String>();
vector.add(new String("hello"));
String str = vector.get(0);

在编译过程中,被重写为:

Vector vector = new Vector();
vector.add(new String("hello"));
String str = (String) vector.get(0);

这跟C++中有很大的不同。在C++中,模板是一个宏设置Macro Set,编译器对每一个类型的模板代码都创建一份拷贝。验证这一点可以通过以下事实: MyClass<Foo>的一个实例不会跟MyClass<Bar>共享一个静态变量,但是两个MyClass<Foo>之间会共享一个静态变量,参见如下代码:

template<class T>
class MyClass {
public:
static int val;
MyClass(int v) { val = v; }
}; template<typename T>
int MyClass<T>::val; class Foo;
class Bar; int main() { MyClass<Foo> *foo1 = new MyClass<Foo>();
MyClass<Foo> *foo2 = new MyClass<Foo>();
MyClass<Bar> *bar1 = new MyClass<Bar>();
MyClass<Bar> *bar2 = new MyClass<Bar>(); cout << foo1->val << endl; // will equal 15
cout << foo2->val << endl; // will equal 15
cout << bar1->val << endl; // will equal 35
cout << bar2->val << endl; // will equal 35 return ;
}

而在Java中,静态变量会在所有的MyClass的实例中共享,不论其参数是否相同,参见下列代码:

public class Foo {}
public class Bar {} public static class MyClass<T> {
public static int val;
public MyClass(int v) { val = v; }
} public static void main (String[] args) {
System.out.println("Hello World!");
MyClass<Foo> foo1 = new MyClass<Foo>(10);
MyClass<Foo> foo2 = new MyClass<Foo>(15);
MyClass<Bar> bar1 = new MyClass<Bar>(20);
MyClass<Bar> bar2 = new MyClass<Bar>(35); System.out.println(foo1.val); // will equal 35
System.out.println(foo2.val); // will equal 35
System.out.println(bar1.val); // will equal 35
System.out.println(bar2.val); // will equal 35
}

由于架构的不同,Java的泛式编程和C++的模板还有许多不同:

- C++可以使用主要类型,例如int,而Java只能使用Integer

- Java中,你可以限制模板的参数类型为一个确定的类型。例如,你可能使用泛式编程来实现一个CardDeck,限定其参数类型必须从CardGame派生过来。

- C++中的参数类型可以被实例化,而Java中的不行。

- 在Java中,参数类型(例如MyClass<Foo>中的Foo)不能用于静态方法或变量,因为这些会被MyClass<Foo>和MyClass<Bar>所共享。而C++中这些类是不同的,所以可以用于静态方法或变量中。

- 在Java中,MyClass的所有实例,不管其参数类型是什么,都是同一个类型,其参数类型在运行时被擦除了。而C++中,拥有不同参数类型的实例是不同的类型。

[CareerCup] 14.4 Templates Java模板的更多相关文章

  1. [CareerCup] 14.2 Try-catch-finally Java中的异常处理

    14.2 In Java, does the finally block get executed if we insert a return statement inside the try blo ...

  2. *关于httl开源Java模板的使用心得

    1.简介 HTTL (Hyper-Text Template Language) 是一个高性能的开源JAVA模板引擎, 适用于动态HTML页面输出, 可替代JSP页面, 指令和Velocity相似. ...

  3. httl开源JAVA模板引擎,动态HTML页面输出

    HTTL(Hyper-Text Template Language)是一个适用于HTML输出的开源JAVA模板引擎,适用于动态HTML页面输出,可用于替代JSP页面,它的指令类似于Velocity. ...

  4. springboot:Java模板引擎Thymeleaf介绍

    Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎.类似JSP,Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用 ...

  5. 新一代Java模板引擎Thymeleaf

    新一代Java模板引擎Thymeleaf-spring,thymeleaf,springboot,java 相关文章-天码营 https://www.tianmaying.com/tutorial/u ...

  6. jetbrick,新一代 Java 模板引擎,具有高性能和高扩展性

    新一代 Java 模板引擎,具有高性能和高扩展性. <!-- Jetbrick Template Engineer --> <dependency> <groupId&g ...

  7. Java 模板引擎 jetbrick-template

    jetbrick-template 是一个新一代 Java 模板引擎,具有高性能和高扩展性. 适合于动态 HTML 页面输出或者代码生成,可替代 JSP 页面或者 Velocity 等模板. 指令和 ...

  8. Java模板引擎 HTTL

    新一代java模板引擎典范 Beetl http://www.oschina.net/p/httl HTTL(Hyper-Text Template Language)是一个高性能的开源JAVA模板引 ...

  9. Ubuntu 14.04下java开发环境的搭建--3--Tomcat及MySQL的安装

    前面两篇文章,已经说明了JDK和Eclipse 的安装方法,下面简单说一下,Tomcat及MySQL的安装方法. Tomcat的安装. 在合适的地方解压apache-tomcat-6.0.39.tar ...

随机推荐

  1. IOS开发关于测试的好的网址资源

    1. 高级自动化单元测试,推荐看LeanCloud 工程师的李智维的自动化单元测试的直播录影李智维的演示github 2.iOS开发-单元测试 这只是一篇简单的ios测试介绍 3.iOS单元测试 来自 ...

  2. 透彻分析反射的基础_Class类

    一.反射的基石--->Class类 1. Java类用于描述一类事物的特性,该类事物有什么属性,没有什么属性,值域这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值 ...

  3. Effective Java 64 Strive for failure atomicity

    Principle Failure atomic - A failed method invocation should leave the object in the state that it w ...

  4. Bootstrap 类解析

    Bootstrap 类解析 元素 Bootstrap 类 定义 <div> container 内容容器 <table> table 表格 <table> tabl ...

  5. linux内核调优参考

    对于新部署的机器,需要做一些基本的调优操作,以更改一些默认配置带来的性能问题 1 修改打开文件数 root@mysql:/data/tools/db# vim /etc/security/limits ...

  6. MongoDB(一)

    问题解决 1.由于目标计算机积极拒绝 无法连接 原因:还没有启动mongodb,就使用mongo命令 解决方法:在bin目录下输入 mongod --dbpath XXXX/data 然后在输入 mo ...

  7. 在Mac 系统上安装密码生成器

    1.打开终端 2.输入 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/ins ...

  8. Mac/Linux 定时运行命令行

    想要开机运行的话可以通过 mac 自带的 Automator 将要运行的命令打包成一个app,用后在用户组的“登录时启动”列表里加上那个app. 但是想要定时运行就不能这么做了,要用上一个叫cront ...

  9. Linux 下子线程 exit code 在主线程中的使用

    Linux线程函数原型是这样的: void* thread_fun(void* arg) 它的返回值是 空类型指针,入口参数也是 空类型指针.那么线程的 exit code 也应该是 void * 类 ...

  10. [转]Try Cloud Messaging for Android

    本文转自:https://developers.google.com/cloud-messaging/android/start