Java 泛型与 C 模板有何不同?为什么我不能使用 int 作为参数?

新手上路,请多包涵

我正在尝试创建

ArrayList<int> myList = new ArrayList<int>();

在 Java 中,但这不起作用。

有人可以解释为什么 int 作为类型参数不起作用吗?

使用 Integerint 原始作品,但有人可以解释为什么 int 不被接受?

Java 版本 1.6

原文由 yesraaj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 759
2 个回答

Java 泛型与 C++ 模板有很大的不同,因此我不打算在这里列出它们的区别。 (有关更多详细信息,请参阅 C++ 和 Java 中的“通用”类型有什么区别?

在这种特殊情况下,问题在于您不能将原语用作泛型类型参数(请参阅 JLS §4.5.1 :“类型参数可能是引用类型或通配符。”)。

但是,由于自动装箱,您可以执行以下操作:

 List<Integer> ints = new ArrayList<Integer>();
ints.add(3); // 3 is autoboxed into Integer.valueOf(3)

这样可以消除一些痛苦。但是,它肯定会损害运行时效率。

原文由 Michael Myers 发布,翻译遵循 CC BY-SA 3.0 许可协议

主要区别在于它们的实现方式,但它们的名称准确地描述了它们的实现。

模板的行为类似于模板。所以,如果你写:

 template<typename T>
void f(T s)
{
    std::cout << s << '\n';
}

...
int x = 0;
f(x);
...

编译器应用模板,因此最终编译器将代码视为:

 void f_generated_with_int(int s)
{
    std::cout << s << '\n';
}

...
int x = 0;
f_generated_with_int(x);
...

因此,对于用于调用 f 的每种类型,都会“生成”一个新代码。

另一方面,泛型仅进行类型检查,但随后会删除所有类型信息。所以,如果你写:

 class X<T> {
    private T x;

    public T getX() { return x; }
    public void setX(T x) { this.x = x; }
}

...
Foo foo = new Foo();
X<Foo> x = new X<>();
x.setX(foo);
foo = x.getX();
...

Java 像这样编译它:

 class X {
    private Object x;

    public Object getX() { return x; }
    public void setX(Object x) { this.x = x; }
}

...
Foo foo = new Foo();
X x = new X();
x.setX(foo);
foo = (Foo)x.getX();
...

到底:

  • 模板需要对模板化函数的每次调用进行实例化(在每个 .cpp 文件的编译中),因此模板的编译速度较慢
  • 使用泛型你不能使用原语,因为它们不是 Object ,所以泛型不太通用

原文由 kravemir 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题