Singleton Design Pattern无法赋值最终变量实例

时间:2016-11-15 18:18:41

标签: java android singleton final

我正在尝试使用ItemControl中的 Singleton设计模式,但Android Studio表示我无法为最终变量'instance'分配值。如果变量必须是静态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;
    }
}

4 个答案:

答案 0 :(得分:0)

你宣布了

private static final ItemControl instance;

由于instancefinal,您无法在方法instance中为getInstance()分配值。必须在声明它,在构造函数中或在初始化块中分配它。

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

答案 1 :(得分:0)

您需要在声明实例时初始化实例:

private static final ItemControl instance = new ItemControl();

答案 2 :(得分:0)

这与Android Studio无关。 请参阅,您已将变量instance声明为final。它被分配到getInstance()。因此,自从它的最终结果以来,你无法将它分配到任何地方,只有它自己。

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

并在getInstance()中返回该变量

public static ItemControl getInstance() {
        return instance;
    }

答案 3 :(得分:0)

我修好了。但我是以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;
    }
}