【问题标题】:Is possible to create Java generics class depending on int value?是否可以根据 int 值创建 Java 泛型类?
【发布时间】:2021-12-09 03:51:21
【问题描述】:
我们可以像这样在 Java 中创建一个泛型类
public class MyClass<T> {
...
但是,现在我正在将(非常大的)C++ 代码转换为 Java,我需要一个类根据其大小与其他类不同,就像在这个 c++ 代码中一样:
template<size_t size> class MyClass {
...
所以每个类都是不同的类型,static 的成员是不同的,像“compare”这样的成员只能用于具有相同 size 的对象。
在 Java 中可以做到这一点吗?如果没有,您将如何处理?
【问题讨论】:
标签:
java
c++
templates
generics
【解决方案1】:
当然,但是很烂。
您可以使用递归类型链来模拟“计数”。Inc<Inc<Inc<Integer>> 可以表示 3。
非常尴尬。
Java 泛型不是 C++ 模板。 Java 泛型有一个通用的基础实现,并自动编写一些包装代码,以将参数化参数转换为瘦包装器中的通用基础。
C++ 模板生成不同的类型。
C++ 模板的设计是为了替换代码生成和/或手动 C 代码低级数据结构。目标是模板类可以匹配甚至超过手写的 C 版本(超过是因为您可以将更多的工程精力投入到单个模板中,并在 100 多个地方重用它)。
像std::function 这样的模板更接近Java 泛型。虽然实现是不同的,但它在这里将无数类型转换为一个接口,对最终用户隐藏了转换。在 C++ 中,这种技术称为类型擦除,其中 std 函数“擦除”有关存储的可调用对象的所有信息,但它公开的内容除外。 C++ 类型擦除不需要公共基类; Java 可以。
但是因为 Java 泛型仅支持一种类型擦除,而 C++ 模板不仅支持更多种类的类型擦除,而且还支持与 Java 完全不同的元编程技术,用 Java 泛型替换模板会一直遇到问题。只有当 C++ 用例恰好与较弱的 Java 泛型完全一致时,它才能正常工作。
(请注意,虽然较弱,Java 泛型使类型擦除更容易,因为它们为您编写了一堆强制转换代码,并对其进行类型检查。较弱并不意味着更糟;它通常意味着更安全。但是机械替换一个系统较弱的系统往往注定要失败。)
【解决方案2】:
不,您不能在 Java 中将值用作参数而不是泛型类型。您可能应该只将大小作为构造函数中的参数,并在考虑大小的情况下实施安全检查。