单例设计模式无法为最终变量实例赋值

Singleton Design Pattern cannot assign value final variable instance

我正在尝试在 ItemControl 中使用 单例设计模式,但是 Android Studio 说我 无法为最终变量赋值 'instance'。如果变量必须是 static final,我该如何编译我的代码?

public final class ItemControl {
    private final Map<Long, Item> itemMap = new HashMap<>();
    private static final ItemControl instance;

    private ItemControl() { }

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

    public void addItem(Item item) {
        itemMap.put(item.getId(), item);
    }

    public List<Item> retrieveItems() {
        if(itemMap.isEmpty()) {
            List<Item> items = carregarItems();
            if(items != null) {
                for(Item item : items) {
                    itemMap.put(item.getId(), item);
                }
            }
        }
        return new ArrayList<>(itemMap.values());
    }

    private List<Item> carregarItems() {
        List<Item> items = new ArrayList<>();

        Item.Builder livroBuilder = new Item.Builder(System.nanoTime(), "Java for Beginners")
                .setAno(2013).setAutor("Glauber Rocha").setQuantidade(3)
                .setDescricao("Livro para programadores iniciantes.");

        Item.Builder revistaBuilder = new Item.Builder(System.nanoTime(), "Geek on the table")
                .setAno(2013).setAutor("Robson Duarte").setQuantidade(2)
                .setDescricao("Revista para geeks.");

        items.add(livroBuilder.build());
        items.add(revistaBuilder.build());

        return items;
    }
}

你声明了

private static final ItemControl instance;

因为 instancefinal 你不能在方法 getInstance() 中给 instance 赋值。它必须在声明时、在构造函数中或在初始化块中赋值。

话虽如此,请考虑将您的单例实现为 enum。如果您不能一起摆脱它,请参阅 What is an efficient way to implement a singleton pattern in Java?

声明时需要初始化实例:

private static final ItemControl instance = new ItemControl();

这与Android工作室无关。 看,您有变量 instance 已声明为 final。并在 getInstance() 中分配。因此,由于它是最终的,你不能将它分配给它本身以外的任何地方。

所以这样做:
private static final ItemControl instance = new ItemControl();

并且在 getInstance() return 那个变量

public static ItemControl getInstance() {
        return instance;
    }

我修好了。但我是按照 java1.5 之前的方式进行的。我不明白如何使用 'enum' 做同样的事情。如何使用枚举来实现相同的单例模式?看了this topic,没看懂

public final class ItemControl {
    private final Map<Long, Item> itemMap = new HashMap<>();
    private static final ItemControl instance = new ItemControl();

    private ItemControl() {
        if(instance != null) {
            throw new IllegalStateException("ItemControl já foi instanciado.");
        }
    }

    public static synchronized ItemControl getInstance() {
        return instance;
    }

    public void addItem(Item item) {
        itemMap.put(item.getId(), item);
    }

    public List<Item> retrieveItems() {
        if(itemMap.isEmpty()) {
            List<Item> items = carregarItems();
            if(items != null) {
                for(Item item : items) {
                    itemMap.put(item.getId(), item);
                }
            }
        }
        return new ArrayList<>(itemMap.values());
    }

    private List<Item> carregarItems() {
        List<Item> items = new ArrayList<>();

        Item.Builder livroBuilder = new Item.Builder(System.nanoTime(), "Java for Beginners")
                .setAno(2013).setAutor("Glauber Rocha").setQuantidade(3)
                .setDescricao("Livro para programadores iniciantes.");

        Item.Builder revistaBuilder = new Item.Builder(System.nanoTime(), "Geek on the table")
                .setAno(2013).setAutor("Robson Duarte").setQuantidade(2)
                .setDescricao("Revista para geeks.");

        items.add(livroBuilder.build());
        items.add(revistaBuilder.build());

        return items;
    }
}