Search code examples
javareinterpret-casttype-systems

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


I have a class Element<T> that contains a T and an int:

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

When no T is stored, I would like to use obj like a pointer to an Element or an index:

obj = someElement;
obj = indexOf(someElement); 

Of course, I can't do that because Java has no unions or variants (as in c++ variants) and has a strict type system.

Note that I would like to be able to access an Element through obj, but I have no desire to change it through obj, if that helps.

Questions:

  1. Is there any way to accomplish this without creating my own variant class or installing one?
  2. If so, what is the most memory efficient way to do this, since I will need to create many Elements?

Solution

  • The small problem is conceptual. An object in java is just some some memory on the heap, and its "address" which is stored in your object field.

    class MyUnion {
        Object any;
    }
    
    MyUnion u = new MyUnion();
    u.any = "hello";
    u.any = Integer.valueOf(13);
    

    The construct above is a union of "addresses," not of data.

    The closest to a union is a byte array, wrapped in a ByteBuffer.

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

    For real Object one must "serialize" them in some form:

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

    For complex binary data one would use ASN or whatever other systematic technique.

    So it is conceptual. You have no objects layouted on the stack (some JVMs do it sneakily), and: objects are indirect.