2017-09-19 57 views
0

在以下代码中,在构造PropertyValue时,会填充两个静态集。这种方式有道理吗?在构造函数中使用静态变量有意义吗?

class PropertyValue{ 

    String cid; 
    String property; 
    String value; 

    public static Set<String> properties = new HashSet<>(); 
    public static Set<String> values = new HashSet<>(); 

    public PropertyValue(String cid, String property, String value) { 
     this.cid = cid; 
     this.property = property; 
     this.value = value; 

     properties.add(property); 
     values.add(value); 
    } 
} 
+4

不,它不。但是分开来说,任何类型的可变静态变量通常都是反模式。 –

+0

更好地让任何客户端代码感兴趣的这些值处理索引。 – chrylis

+0

这不工作像一个静态柜台? – marlon

回答

1

你应该做一个成员变量静态的唯一情况是,如果你不想成员的生命绑在对象的生命做。也许你有一个在创建或销毁的对象之间共享的计数器。或者,也许你有一个函数需要在对象实例化或创建之前持久化。也许你有一个由子类共享的静态成员的基类。那些是我通常只让会员变成静态的时候。

在你的例子中很难说,因为不知道类是如何实现的全部范围,所以很难判断它是否有意义。

1

除了静态设置的是否是一个好主意......

的代码应放置在一个静态初始化。这可确保在加载类时静态内容已准备就绪。根据类的设计,有可能构造函数永远不会被调用。

static { 
    // do the work 
} 
+1

*代码应该放置在一个静态初始化器中。*编号'public static Set properties = new HashSet <>();'不需要在'static {}块中。静态初始化与'static {}'块完全相同。 –

1

至于设计去... ...

公共领域,在这种情况下设置的,通常是一个坏主意。如果其他类需要访问Set,他们应该通过静态方法来完成。

Static Set和Map在所有类的实例都使用配置信息的情况下有意义。但是,通常不应允许实例修改内容。正如我在前面的回答中指出的,应该使用静态初始化程序来加载Set或Map。

2

它似乎是一种关键值对缓存设计,但非线程安全。

为什么两组代替一个Map?

你可以做一个单身持有人线程单和一个Hashtable

https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom

import java.util.Hashtable; 
import java.util.Map; 

public class Properties 
{ 
    private Map<String,String> properties = new Hashtable<>(); 

    private Properties(){} 

    private static class PropertiesHolder{ 
     private final static Properties instance = new Properties(); 
    } 

    public static Properties getInstance(){ 
     return PropertiesHolder.instance; 
    } 

    public void put(String property, String value){ 
     properties.put(property, value); 
    } 

    public void get(String property){ 
     properties.get(property); 
    } 
} 

,并使用

Properties properties = Properties.getInstance(); 
    properties.put("foo","bar"); 
    properties.get("foo"); 

与全班同学

class PropertyValue{ 

    String cid; 
    String property; 
    String value; 

    public PropertyValue(String cid, String property, String value) { 
     this.cid = cid; 
     this.property = property; 
     this.value = value; 

     Properties properties = Properties.getInstance(); 
     properties.put(property, value); 
    } 
} 

但我认为这不是PropertyValue类的维护此关键值“store”的响应性。 此存储应该在新的PropertyValue实例之后(或之前)填充,但不在构造函数中填充。

https://en.wikipedia.org/wiki/Single_responsibility_principle

你可以把你的两组字符串,如果你不需要通过对的属性和数据存储,或者直接存储一组的的PropertyValue在单

+0

这完全改变了发布代码的行为 - 两个值的单独和独立集合,大概是简单地保持一组遇到的每个单独的值。 (这是我的一个假设)使用您所发布的Map <>'改变了代码的全部含义,从仅仅追踪遇到的情况到以无意义的方式将两个值映射在一起。你认为这是OP所需要的。 *一个静态字段是由线程唯一的*是什么意思?你的实现也不是线程安全的 - 它是* same * HashMap <>的并发修改。 –

+0

好的,这是真的,我改变了很多的代码来帮助,也许这不是一个好主意,但我认为它是线程安全的(参见我的链接:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom),它是不难适应这个代码来保存这两个集合 –

+0

你对它不是线程安全的,因为HashMap没有同步,我的不好。它通过使用同步的Hashtable来纠正 –

相关问题