Search code examples
javageneric-type-argument

How to create an object according to the objects passed in java


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.


Solution

  • 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);
            }
        }
    }