Question

I have a bunch of classes that I have already loaded and already done newInstance() on the classes. I would like to reuse these classes without needing to do a newInstance() again and also reuse their current states. Is there a method to replace the use of newInstance() so that I can reuse already instantiated classes without recreating them (thus losing all the states). How should I go about it ?

List<Class> classes = null;

private void parseCP(File loadPath) {
        try {
            // Convert loading path to a URL
            URL url = loadPath.toURI().toURL();
            URL[] urls = new URL[]{url};

            // Create a new class loader with the directory
            ClassLoader cl = new URLClassLoader(urls);

            classes = getClassesFromFolder(loadPath.getPath(), cl);
            System.out.println("Classes discovered: " + classes.size());
            for (Class i : classes) {

                System.out.println("Looking into class: " + i.getName());
                Object obj = i.newInstance();

                // Call load() to get HttpFunctions to register their main and sub functions.
                Method loadMethod = i.getMethod("load", null);
                Object loadRes = loadMethod.invoke(obj, null);
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public Object invoke(String classname, String method, Object args) {
        Object res = null;
        try {
            for (Class i : classes) {
                if (i.getName().equals(classname)) {
                    Object obj = i.newInstance();  //<--- How do I NOT create newInstance but reuse them ?
                    Class[] cargs = new Class[1];
                    cargs[0] = Object.class;
                    Method loadMethod;
                    if (args != null) {
                        loadMethod = i.getMethod(method, cargs);
                    } else {
                        loadMethod = i.getMethod(method, null);
                    }
                    if (loadMethod != null) {
                        if (args == null) {
                            res = loadMethod.invoke(obj);
                        } else {
                            res = loadMethod.invoke(obj, args);
                        }
                    }
                }
            }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return res;
    }

Note: I have a previous post regarding classloading but the problems behind these 2 posts are not the same.

Was it helpful?

Solution

You can just use a HashMap to store the Objects

public static HashMap<Class, Object> instances = new HashMap<Class, Object>();
public Object getInstance(Class clazz) {
    if (instances.constainsKey(clazz)) {
        return instances.get(clazz);
    } else {
        Object o = clazz.newInstance();
        instances.put(clazz, o);
        return o
    }
}

But I don't actually understand the purpose and there seems like there's a better way to solve your problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top