How to create object of a particular type when the parameter passed in is generic? Here is what I have:
public class Sample{
static ArrayList<Bus> buses;
static ArrayList<Taxi> taxis;
static ArrayList<Truck> trucks;
public static void main(String[] args) {
readInFile("busStates.txt",buses);
readInFile("taxiStates.txt",taxis);
readInFile("truckStates.txt",trucks);
}
public static <T> void readInFile(String fileName, ArrayList <T> targetList){
Scanner inFile = new Scanner(new FileInputStream(fileName));
while(inFile.hasNextLine()){
T t = new T(inFile.nextLine().split("\t")); //this failed.
//I hope it can do Bus t = new Bus(params) when busList is passed in
targetList.add(t);
}
}
I thought java will be able to create Bus object when I passed in the busList<> which will contain Bus objects.
Are there any way to initialize object based on the type of parameter passed in? I want my program to invoke Bus constructor when busList is passed in and do the same for taxiList, truckList.
Side note: Bus, Taxi and Truck extends a common superclass.
Thank you.
I assume your classes Bus
, Taxi
and Truck
all extend from the common superclass Vehicle
.
You can solve your problem by adding one more argument of type Class<T>
to your readInFile
method indicating the class of vehicles to be created.
public static void main(String[] args) throws IOException {
readInFile("busStates.txt", buses, Bus.class);
readInFile("taxiStates.txt", taxis, Taxi.class);
readInFile("truckStates.txt", trucks, Truck.class);
}
In the reading method you use the Class<T>
argument
to get the Constructor<T>
of that class accepting a String[]
parameter,
and then you call this constructor to create the actual T
object.
public static <T extends Vehicle> void readInFile(String fileName, ArrayList<T> targetList, Class<T> clazz) throws IOException {
Scanner inFile = new Scanner(new FileInputStream(fileName));
while (inFile.hasNextLine()){
String[] params = inFile.nextLine().split("\t");
try {
Constructor<T> constructor = clazz.getConstructor(String[].class);
T t = constructor.newInstance((Object[]) params);
targetList.add(t);
} catch (NoSuchMethodException | SecurityException | InstantiationException |
IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException("Problem with constructor", e);
}
}
}