有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中使用双重检查锁定单例扩展类

我有一门课是这样的:

public class Contact {

    private static volatile Contact instance;

    private List<Item> contacts = new ArrayList<>();
    private Context context;

    public static Contact getInstance(Context context) {
        Contact localInstance = instance;
        if (localInstance == null) {
            synchronized (Contact.class) {
                localInstance = instance;
                if (localInstance == null) {
                    instance = localInstance = new Contact(context);
                }
            }
        }
        return localInstance;
    }

    public Contact(BaseAuthActivity context) {
        this.context = context;
        update();
    }

这里我创建了一个类的实例,在class属性上进行同步

我的项目中有很多这样的课程。有没有一种方法可以创建一个基类来实现getInstance方法,这样我就不需要在所有的类中都保留这段代码了?我尝试使用泛型,但没有成功。也许有一个例子可以说明我想要达到的目标


共 (1) 个答案

  1. # 1 楼答案

    实现这一点的一种方法是保存来自要实例化的Class对象和正在使用的单例实例的映射。假设您的所有类都有一个来自Context的公共构造函数,您可以使用反射来调用它:

    public class Contact {
    
        private static ConcurrentMap<Class<? extends Contact>, Contact> instances = 
            new ConcurrentHashMap<>();
    
        public static <T extends Contact> T getInstance
            (Context context, Class<T> clazz) {
    
            T instance = (T) instances.get(clazz);
            if (instance == null) {
                synchronized (clazz) {
                    instance = (T) instances.get(clazz);
                    if (instance == null) {
                        try {
                            Constructor<T> constructor = 
                                clazz.getConstructor(Context.class);
                            return constructor.newInstance(constructor);
                        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
                            // log
                            return null;
                        }
                    }
                }
            }
            return instance;
        }
    }