如何使用反射防止多个对象创建

时间:2016-04-05 10:08:39

标签: java design-patterns reflection

我有用于返回对象实例的方法。使用反射我得到的类实例很好。  我需要避免每次为同一个类创建一个新对象。 我错过了什么吗?

private static Object getInstance(String clazz) 
{
    //full path of the class in the clazz

    Class<?> c = null;
    Object obj = null;

    try 
    {
        c = Class.forName(clazz);
        System.out.println("inside ins" + c);
        obj = c.newInstance();
    } 
    catch (Exception e) 
    {
        System.out.println(e);
    }
    return obj;
}

Object inst = getInstance("com.test.Test1");
Method method = inst.getClass().getMethod("getVal", String.class,String.class);
method.invoke(inst, "new params","ss");

感谢

2 个答案:

答案 0 :(得分:1)

以下是您可以继续的方式:

private static final ConcurrentMap<String, FutureTask<Object>> INSTANCES = new ConcurrentHashMap<>();

private static Object getInstance(String clazz) throws InterruptedException, ExecutionException {//full path of the class in the clazz
    FutureTask<Object> task = new FutureTask<>(() -> Class.forName(clazz).newInstance());
    FutureTask<Object> previous = INSTANCES.putIfAbsent(clazz, task);
    if (previous == null) {
        task.run();
    } else {
        task = previous;
    }
    return task.get();
}

以下是相同的代码,但对于Java 1.7

private static final ConcurrentMap<String, FutureTask<Object>> INSTANCES = new ConcurrentHashMap<>();

private static Object getInstance(final String clazz) throws InterruptedException, ExecutionException {//full path of the class in the clazz
    FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
        @Override
        public Object call() throws Exception {
            return Class.forName(clazz).newInstance();
        }
    });
    FutureTask<Object> previous = INSTANCES.putIfAbsent(clazz, task);
    if (previous == null) {
        task.run();
    } else {
        task = previous;
    }
    return task.get();
}

答案 1 :(得分:0)

这里的一种可能性是实现您想要作为单身返回的类。然后在你的getInstance()方法中,你可以调用单例的getInstance()方法(或任何你想要的方法)。例如,您的单例类看起来像这样:

public class ClassOne {

   private static ClassOne instance;

   public static ClassOne getInstance() {
      if (instance==null) {
         instance = new ClassOne();
      }
      return instance;
   }
}

并且您的getInstance()方法将被修改为看起来像这样。 (请注意,此代码尚未经过测试,但我之前已完成此操作,因此原则确实有效)

private static Object getInstance(String clazz) {//full path of the class in the clazz
    Class<?> c = null;
    Object obj = null;
    try {
        c = Class.forName(clazz);
        System.out.println("inside ins" + c);
        Method method = c.getMethod("getInstance", null);
        obj = method.invoke(null, null);

    } catch (Exception e) {
        System.out.println(e);
    }
    return obj;
}

因此,您基本上只是委托控制何时为类本身创建新实例。根据您希望以这种方式调用的类,可以将单例行为抽象为可以继承的单独类,但是在使用这样的反射时这可能有点棘手。