您对内存泄漏问题
我想说这里会有没有内存泄漏问题开始。实际上,这两种情况下的内存泄漏完全相反(在这方面它们是相同的)。 DataHolder类只能有一个String实例(因为它是静态的,它不属于任何DataHolder实例)。
想象一下,这是不是静态的:
public class DataHolder
{
String dataString;
}
这意味着,每一次这样做new DataHolder()
,你将有一个字符串的一个单独的实例。用你的静态dataString,只会有一个实例。
getter和setter和同步
之所以你的实现是坏的,因为它不是线程安全的,因为米塔尔的Piyush指出。尽管他没有涉及任何细节,所以我想补充两分钱。
你不能说这仅仅是因为你只希望它在一个线程中使用,它只会在一个线程中使用。 Swing线程就是一个很好的例子,其中只有一个线程处理UI。在这种情况下,你会期望只有一个线程存在,并且可以这样做。但是,任何后台工作都必须在SwingWorker线程中完成,因此在此创建一个SwingWorker线程来提供数据竞争机会,因为现在有两个线程。出于这个原因,你应该总是有静态变量的getter和setter。
这就是说,您提供的代码片段与您的两个示例(由于没有同步生成新堆栈帧的小差异)完全相同。你想这样做:
public class DataHolder{
private static String dataString;
public static String getDataString(){
synchronized(DataHolder.class){
return DataHolder.dataString;
}
}
public static void setString(String dataString){
synchronized(DataHolder.class){
DataHolder.dataString = dataString;
}
}
}
我确实改变了一些关于你的代码的东西。第一个也是最明显的是没有这个关键字用于静态变量。正如我之前暗示的那样,因为它的静态不属于任何实例。 “这个”在静态环境中不是一件事情。
我做的另一件事是放在方法的同步内部。我这样做有两个原因。首先是偏好;有些人更喜欢保持同步的功能签名,所以它从调用者混淆,所以他们不做假设,因为该功能是同步的。这是首选。我做这件事的另一个原因是因为我想明显地表明,当你在签名中同步一个函数时,它实际上将看起来是“底层的”。如前所述,由于没有“this”,它实际上将在类本身上进行同步。
我想你大概可以使用一些关于static关键字的阅读。我认为你的困惑来自于你不了解它的事实,并且在理解静态本身之前,你试图回答关于静态变量的getter和setter的问题。这里有一个链接,我找到一个快速的谷歌搜索,可能让你开始: http://www.javatpoint.com/static-keyword-in-java
'静态'方法很少用于这些尝试('get'或'set')。 – Andrew
您正在隐藏实现细节(如所有封装)。这使您可以修改它而不会破坏代码。如果你想以“Data”类型存储数据,你可以改变字段变量,然后在'setString'方法(我建议改变名字)和'Data'中将'String'解析为'Data' ''getString'方法中的'String'。 –
你可能想要阅读这个链接,主要讨论需要首先获取/设置方法! http://stackoverflow.com/questions/1568091/why-use-getters-and-setters?lq=1 – AADProgramming