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:
- Is there any way to accomplish this without creating my own variant class or installing one?
- If so, what is the most memory efficient way to do this, since I will need to create many Elements?
CodePudding user response:
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.
CodePudding user response:
One way to approach this is by using an interface, or a super class with inheritance.
For example, if we had the following Java interface:
interface Element<T> {
T getValue();
}
then any class that implements the Element
interface would need to provide a method that returned the value of an element.
We could implement a class that stored a T
type object and returns it:
class ElementObject<T> implements Element<T> {
private T object;
T getValue() {
return object;
}
}
Or we could implement a class that stores an index and uses it (in conjunction with some big list of objects):
class ElementIndex<T> implements Element<T> {
private int index;
T getValue() {
return bigListOfObjects.get(index);
}
}
Now you could create a list or array or Element
s and some of them could be ElementObject
s and some could be ElementIndex
s but they would both provide the access to an element as desired, without any wasted fields in either one.