是否有任何内存高效 Java 等同于 C 联合或 C++ std::variant?

Is There Any Memory-Efficient Java Equivalent to C unions or C++ std::variant?

我有一个 class Element<T>,其中包含一个 T 和一个 int:

class Element<T>{
    T obj;
    int i;
    // ...
}

当没有存储 T 时,我想使用 obj 作为指向元素或索引的指针:

obj = someElement;
obj = indexOf(someElement); 

当然,我不能那样做,因为 Java 没有联合或变体(如在 c++ 变体中)并且有严格的类型系统。

请注意,我希望能够通过 obj 访问元素,但我不想通过 obj 更改它,如果有帮助的话。

问题:

  1. 有什么方法可以在不创建我自己的变体的情况下完成这个 class 还是安装一个?
  2. 如果是这样,执行此操作的内存效率最高的方法是什么,因为我 需要创建很多元素吗?

小问题是概念上的。 java 中的对象只是堆上的一些内存,其“地址”存储在您的对象字段中。

class MyUnion {
    Object any;
}

MyUnion u = new MyUnion();
u.any = "hello";
u.any = Integer.valueOf(13);

上面的构造是“地址”而非数据的并集。

最接近联合的是字节数组,包装在 ByteBuffer 中。

ByteBuffer u = ByteBuffer.allocate(8);
u.putDouble(0, 3.14);
long x = u.getLong(0);

对于真正的对象,必须以某种形式“序列化”它们:

String obj = "Ĉeĥoslovakio";
byte[] b = obj.getBytes(StandardCharsets.UTF_8);
u.putInt(b.length);
u.put(b);

对于复杂的二进制数据,可以使用 ASN 或任何其他系统技术。

所以这是概念性的。您没有在堆栈上布局对象(一些 JVM 偷偷地这样做),并且:对象是间接的

解决此问题的一种方法是使用接口或具有继承的超级 class。

例如,如果我们有以下 Java 接口:

 interface Element<T> {
     T getValue();
 }

那么任何实现 Element 接口的 class 都需要提供一个返回元素值的方法。

我们可以实现一个 class 来存储一个 T 类型的对象和 returns 它:

 class ElementObject<T> implements Element<T> {

     private T object;

     T getValue() {
         return object;
     }
  }

或者我们可以实现一个 class 来存储索引并使用它(结合一些大的对象列表):

 class ElementIndex<T> implements Element<T> {

     private int index;

     T getValue() {
         return bigListOfObjects.get(index);
     }
  }

现在您可以创建一个列表或数组或 Elements,其中一些可以是 ElementObjects,一些可以是 ElementIndexs,但它们都可以提供对一个所需的元素,其中任何一个都没有任何浪费的字段。