【问题标题】:Is There Any Memory-Efficient Java Equivalent to C unions or C++ std::variant?是否有任何等效于 C 联合或 C++ std::variant 的内存高效 Java?
【发布时间】:2021-12-03 03:55:11
【问题描述】:

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

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

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

obj = someElement;
obj = indexOf(someElement); 

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

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

问题:

  1. 有什么方法可以在不创建我自己的变体的情况下完成此任务 上课还是安装?
  2. 如果是这样,什么是最节省内存的方法,因为我 需要创建许多元素吗?

【问题讨论】:

  • 可以给Element类添加一个成员,类型为Object,我们称之为obj。在 Java 中,一切都是参考(C++ 中的一种“指针”,具有巨大的“类型”..)。因此,您可以为该 obj 分配您想要的任何对象。然后,如果 T 为 null,则使用 obj。
  • 这听起来像XY problem。你想在这里做什么
  • Element&lt;T&gt; 类的字段obj 是对堆上某处对象的引用。 Java 中只存储原语

标签: java reinterpret-cast type-systems


【解决方案1】:

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

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

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

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

我们可以实现一个类来存储T 类型的对象并返回它:

 class ElementObject<T> implements Element<T> {

     private T object;

     T getValue() {
         return object;
     }
  }

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

 class ElementIndex<T> implements Element<T> {

     private int index;

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

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

【讨论】:

    【解决方案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 偷偷摸摸地这样做),并且:对象是间接的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      相关资源
      最近更新 更多