vendredi 22 mai 2015

Getting instance of singleton via reflection

I was wondering is there anyway to get the instance of a singleton class via reflection. Apparently it can be doable in c# as question 17828039 of stackoverflow mentioned but I couldn't find any useful resources to do it in Java.

my model classes are:

public class Parent {
    public void info(){
        System.out.println("inside parent info");
    }

}

and

public class Child extends Parent{
    @Override
    public void info() {
        System.out.println("inside child info");
    }
}

and I've also written the following test class that fails and gives me exception :)

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;


public class Main {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        Parent oo = new Child();
        HashMap<Class<? extends Parent>, Class<? extends Filler>> map = new HashMap<Class<? extends Parent>, Class<? extends Filler>>();
        map.put(Parent.class, ParentFiller.class);
        map.put(Child.class, ChildrenFiller.class);
        Class<?> cls  = map.get(oo.getClass());
        Object obj = null;
        Method getinst = null;
        try{
            getinst= cls.getDeclaredMethod("getInstance",new Class[] {});
             obj = getinst.invoke(null, null);
             }catch(NoSuchMethodException e){
//               try {
//                   obj = cls.newInstance();
//               } catch (InstantiationException e) {
                     e.printStackTrace();
//               }
         }
//      Filler filler = map.get(p.getClass()).newInstance();
//      filler.fill().info();;
    }
}
interface Filler<T extends Parent>{
    public T fill();
    public Filler getInstance();
}
class ParentFiller implements Filler<Parent>{

    private static ParentFiller filler;

    @Override
    public  Parent fill() {
        return new Parent();
    }

    @Override
    public ParentFiller getInstance() {
        synchronized (this) {
            if(filler == null){
                filler =  new ParentFiller();
            }
        } 
        return filler;
    }

}

class ChildrenFiller implements Filler<Child>{
    private static ChildrenFiller filler;
    private ChildrenFiller() {}
    @Override
    public Child fill() {
        return new Child();
    }

    @Override
    public ChildrenFiller getInstance() {
        if(filler == null){
            synchronized (this) {
                if(filler == null){
                    filler =  new ChildrenFiller();
                }
            } 

        }
        return filler;
    }
}





Aucun commentaire:

Enregistrer un commentaire