0

I have a data holder instance of String, integer, double, ... and I'm saving the data to (Oblect dataHolder) and (Class dataHolderClass). My question is how to cast back the dataHolder to int, String ...?

For instance I have the following data class:

class DataHolderClass {
    private Object data;
    private Class classData;

    DataHolderClass(Object data, Class dataClass) {
        this.data = data;
        this.classData = dataClass;
    }

    Object getDataBack() {
        return this.data;
    }

    Class getDataClassBack() {
        return this.classData;
    }
}

So how can I cast the data back knowing the dataClass and having the data? And here is some calling code (not sure if it is possible to do such kind of magic):

.....
public void foo(DataHolderClass input) {
    Class inputClass = input.getDataClassBack();
    Constructor constr = inputClass.getConstructor();
    DataType recoveredData = constr.newInstance();
    //  ^------- the DataType is defined in inputClass but how can I get it?
    recoveredData = (DataType) input.getDataBack();
    ...
}
6
  • 4
    By using a generic type. Commented Jan 15, 2017 at 15:56
  • I do not understand. Cast to what? If the calling site already has a variable of some type to store the data into, that is the type to cast to. If it doesn't, why do you need to cast? Commented Jan 15, 2017 at 17:24
  • I have a second class with a method that gets DataHolderClass as an argument. Extracts the data from the DataHolderClass object and uses it (for something). But it casts the data back (somehow) to the original data type (classData). Commented Jan 15, 2017 at 18:07
  • Please post the code concerned. It doesn't make sense yet. The calling code has to be written statically around a specific datatype. You can't have a variable datatype. Commented Jan 15, 2017 at 23:02
  • Do you mean dataClass.cast(data)? But it doesn't sound like you'd need this. If your caller already knows to put the result into the variable of type DataType, why would you need to cast reflectively? If it doesn't know the DataType type ahead of time, than it needs to store it into Object variable anyway, so why the cast? You can't choose a variable type at runtime. Commented Jan 16, 2017 at 11:12

2 Answers 2

2

It is here since java 5 - generics.

class DataHolderClass<T> {
    T data;

    DataHolderClass(T data) { ... }
    T getData() { 
        return data;
    }
}

You have type safety out of box.

Sign up to request clarification or add additional context in comments.

4 Comments

I know how to use generics, but how can I cast it back if I send it to another method that knows only that its argument is DataHolderClass object? It can extract the data, extract the Class, but how can cast it back?
Change method from foo(DataHodlerClass) to <T> foo(DataHolderClass<T>)
This is when the data type contained in DataHolderClass is predefined. And what if I want to use DataHolderClass as an universal container that can also give me information about the contained data type? And how to cast it back to the original type (T, String, Integer..) without if-else statement?
Please, provide a use case. You do not need "a universal container". You need a container for certain case.
0

If you can limit the options what DataObject can be, you can use an if/else sequence with the instanceof check like

 Integer castInt;
 Double castDbl;
 String castStr;  
 if (dataObject instanceof Integer) castInt = (Integer) dataObject;
 else if (dataObject instanceof Double) castDbl = (Double) dataObject;
 else if (dataObject instanceof Double) castStr = (String) dataObject;

That done you end up with the problem what cast field to use from thereon.

1 Comment

Is there a roundabout way to define the data type without if-else statement and only one data container, but not 3 separated containers for Integer, Double and String? What about Reflection? Is this a solution and how?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.