我在专业软件开发领域的编程相当新,我的同事讨论了如何在Spring @Service注释类中使用以下字段:
private static final Map<Key, Value> someMap;
static {
Map<Key, Value> map = new HashMap<>();
map.put(aKey, aValue);
someMap = Collections.unmodifiableMap(map);
}
我可以在不影响以下前提下的某些安全/功能的情况下遗漏任何关键字:
这种方法比使用这样的方法有什么优点或缺点:
private final Map<Key, Value> someMap;
public MyClass() {
Map<Key, Value> map = new HashMap<>();
map.put(aKey, aValue);
someMap = Collections.unmodifiableMap(map);
}
答案 0 :(得分:1)
您应该问自己的主要问题是您要创建的课程的实例数量。
一个班级实例
@Service的默认范围是单身,那么无论是将地图创建为静态成员还是常规成员,都没有太大区别。只有一个地图实例,唯一的区别在于它的初始化发生的那一刻。使用单例范围没有真正的理由使用静态成员。
但是,通过将地图创建为该类的常规成员,您可以避免将来静态成员出现问题。例如,如果你想对你的类进行单元测试并为某些测试场景存储地图,那么对于静态成员来说会更成问题。静态成员可以从依赖注入和@Value注入中受益,以备不时之需。
许多班级实例
如果更改了@Service类的默认范围,并且您希望所有实例共享一些私有内部状态,那么在某些情况下使用静态成员可能是一个合理的选择。您必须记住,实例可以同时访问或修改地图,因此您应该确保在设计类时考虑到线程安全。
答案 1 :(得分:0)
这两种方法在成员someMap
的范围上有所不同;一个是static
,另一个是实例成员。这是一个逻辑问题 - 成员应该属于类,或者它应该属于实例。您还没有在特定情况下向我们提供足够的信息,但如果班级的多个实例需要访问课程中的相同地图,那么它显然必须是static
。在这种情况下,实例方法的缺点是程序会中断。 OTOH,如果每个实例都需要自己的地图,那么它就是打破程序的static
版本。
所以你告诉我们 - 地图属于班级,还是属于班级的每个实例?
此外,除非其元素也是,否则地图不是不可变的。你无法改变地图中的内容,但是如果这些键是可变的,你可能会得到一些非常奇特的结果。