Fabian N. Fabian N. - 1 month ago 6
Java Question

Creating a instance of a typed class with a variable in java

I have a class with a type

public class Scan<T extends Data>{
...
}


Data
is a abstract type, from which I have some Implementations.

Now I want some kind of chooser, which implementation to use. Is this possible? If yes, which type must the variable have (I tried with
Class
, but this does not work)

Class datatype;
switch(datatypeInt){
case 2:
datatype = Simple3DData.class;
break;
case 1:
default:
datatype = Simple2DData.class;
}

Scan<datatype> scan = new Scan<>();


(Obvious this does not work)

I can't instantiate Scan in the switch block, because I will also choose the Scan class at some point dynamically.

EDIT:
I see, this is not possible that easy, I will try convert the code, not to use types, rather replacing all my
T
by
Data
and passing the
Class
object as parameter for my Scan.

Answer

What you try to achieve cannot work because type parameters are only used at compile time by the compiler to make sure that your code is compliant with the types defined in order to avoid getting at runtime exceptions of type ClassCastException.

At runtime, type parameters don't even exist anymore due to type erasure, such that your code would be something like this:

Class datatype;
switch(datatypeInt){
  case 2:
    datatype = Simple3DData.class;
    break;
  case 1:
  default:
    datatype = Simple2DData.class;
}
Scan = new Scan();

Which means that you need to specify the class explicitly, so your code could be something like this:

Class<? extends Data> datatype;
switch(datatypeInt){
  case 2:
    datatype = Simple3DData.class;
    break;
  case 1:
  default:
    datatype = Simple2DData.class;
}
Scan scan = new Scan(datatype);

A much more OO approach could be to implement the strategy pattern, you could have one scanning strategy per type of data, the code would then be:

ScanStrategy strategy;
switch(datatypeInt){
  case 2:
    strategy = new Simple3DDataScanner();
    break;
  case 1:
  default:
    strategy = new Simple2DDataScanner();
}
Scan scan = new Scan(strategy);