vendredi 18 mars 2016

JAVA: Cast String to (dynamically known) primitive type in order to instantiate a (dynamically known) class

I have a repository class that uses text files(a requirement), meaning that I have to read strings and cast them in order to instantiate objects. The problem is that I want my repository class as general as I can make it, in order to use it to manipulate different object types.

So, is there a (more elegant) way to dynamically cast strings to whatever field (primitive) type it needs at runtime, while avoiding lots of try-catch structures with numerous ifs/switches?

As a short simplified version, I want objectA.txt to contain only objectA's information, similarly for objectB.txt, and my Repository code to handle both:

Repository repoA = new Repository("objectA.txt", < list of Types for A >); TypeA a=repoA.getOne();

Repository repoB = new Repository("objectB.txt", < list of Types for B >); TypeB b=repoB.getOne();

What I have:

public class FileRepository extends InMemoryRepository{
    private String fileName;
    private List<Class> types;

    public FileRepository(String fileName, List<Class> types) {
        //@param types 
        //     - list containing the Class to be instantiated followed by it's field types
        super();
        this.fileName = fileName;
        this.types=types;
        loadData();
    }

    private void loadData() {
        Path path = Paths.get(fileName);

        try {
            Files.lines(path).forEach(line -> {
                List<String> items = Arrays.asList(line.split(","));

                //create Class array for calling the correct constructor
                Class[] cls=new Class[types.size()-1];
                for (int i=1; i<types.size(); i++){
                    cls[i-1]=types.get(i);
                }

                Constructor constr=null;
                try {
                    //get the needed constructor
                    constr = types.get(0).getConstructor(cls);
                } catch (NoSuchMethodException e) {
                    //do something
                    e.printStackTrace();
                }
                //here is where the fun begins
                //@arg0 ... @argn are the primitives that need to be casted from string 
                //something like: 
                //*(type.get(1))* arg0=*(cast to types.get(1))* items.get(0);
                //*(type.get(2))* arg1=*(cast to types.get(2))* items.get(1);
                //...

                Object obj= (Object) constr.newInstance(@arg0 ... @argn);

            });
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

P.S.: I'm a JAVA newbie, so please keep the explanations as simple as possible.





Aucun commentaire:

Enregistrer un commentaire