单例设计模式无法为最终变量实例赋值
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;
因为 instance
是 final
你不能在方法 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;
}
}
我正在尝试在 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;
因为 instance
是 final
你不能在方法 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;
}
}