ping pong
ping pong

Reputation: 275

Parse Java reflection class

Let's say I have a method called Object classInstance = createInstance("Page", map, factory) which creates an instance of "Page" with java reflection and does some stuff with it. For demonstration purposes I've called it "Page", but it could be any of my classes.

Now I want to add this object to a List<Page>. To call list.add(classInstance) and add it to the list I need to parse it to "Page". Is there a way to do it, given the only information I have is the string containing the class name? So instead of doing (Page) classInstance I need to do something like (Class.forName("Page")) classInstance.

I can not modify the List or the way it is added to the list.

Thank you.

Edit: here is the createInstance Method:

    private static Object createInstance(String className, Map<?, ?> map, Meilenstein2Factory factory) throws InvocationTargetException, IllegalAccessException {

    try {
        String createMethodName = "create" + className;
        Method createMethod = factory.getClass().getMethod(createMethodName);
        Object classInstance = createMethod.invoke(factory);
        
        
        String methodName = "";
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            try {
                methodName = "set" + entry.getKey().toString().substring(0,1).toUpperCase() + entry.getKey().toString().substring(1);
                Method setNameMethod = classInstance.getClass().getMethod(methodName, getType(entry.getValue()));
                setNameMethod.invoke(classInstance, parseEntry(entry.getValue()));
            } catch (NoSuchMethodException e) {
                LOGGER.log(null, "Attribute " + entry.getKey().toString() + " is not a valid attribute for this object. Is it spelled correctly?");
            }
            
        }
        return classInstance;
    } catch(NoSuchMethodException nm) {
        LOGGER.log(null, "Folder " + className + " does not reference to a valid object. Is it spelled correctly?");
    }
    return null;

}

Edit 2: Screenshots of error and debugger

Do not bother about Page and PageImpl, I used Page in my question to simplify, but the factory accepts the Interface Page and returns an instance of PageImpl. As you can see in the second screenshot, the object is an instance of PageImpl, so this seems to be correct.

enter image description here

enter image description here

Edit 3: enter image description here

Edit 4: Something that works for now:

String methodName = "get" + "Page";
        Method getListMethod = site.getClass().getMethod(methodName);
        List<Object> list = (List<Object>) getListMethod.invoke(site);
        list.add(page);

Upvotes: 1

Views: 468

Answers (1)

Matteo NNZ
Matteo NNZ

Reputation: 12665

Your method createInstance returns a Class<Page> (the class object), but your list is a List<Page> (a list of instances).

You will need to create an instance and add it to the list, still using reflection:

list.add(classInstance.getDeclaredConstructor().newInstance());

The above is using an empty constructor for the class Page. If for example you wanted to use a constructor taking one string and one int, you would do it as such:

list.add(classInstance.getDeclaredConstructor(String.class, Integer.class).newInstance("my string", 4));

Edit:. Since classInstance is an Object and not a class, you should be able to do this:

list.add(Class.forName("Page").cast(classInstance));

Upvotes: 2

Related Questions