我搜索了保存/共享全局使用数据的最佳方法,并且按照预期我找到了很多答案。引起我注意的方法之一是使用静态字段。然而,那里所说的静态场方式是这样的:
public class DataHolder
{
private static String dataString;
public static String getDataString
{
return dataString;
}
public static void setString(String dataString)
{
this.dataString = dataString;
}
}
但我总是这样做:
public class DataHolder
{
public static String dataString;
}
我只是想知道后者不比第一个容易得多吗?因为我不必设置任何getter和setter方法。我认为这两者之间没有任何区别。那么为什么不推荐第二个?
之前我也被告知,按照我的方式行事会导致内存泄漏问题。但第一种解决方案不会导致内存泄漏问题吗?
答案 0 :(得分:1)
对内存泄漏不太了解。
但是:多个并行请求 - 多个线程,你肯定有一个线程问题 - 这不是线程安全的除非你照顾(例如使用 synchronized )
答案 1 :(得分:1)
我更喜欢getter / setter,而不是公共领域。
这种封装允许您修改属性类型,而不会破坏使用它的代码。
如果您决定创建Data
类型,而不是将其存储为String
,该怎么办? (为了增加类型安全性)。
有了公共领域,这是不可能的。但是使用getter / setter,您可以执行允许此操作所需的解析:
class SomeClass {
private static Data data;
public static void setData(String data) {
data = new Data(data);
}
public static String getData() {
return data.toString();
}
}
class Data {
private String data;
public Data(String data) {
this.data = data;
}
public String toString() {
return data;
}
}
这不是内存泄漏问题,因为它与分配内存无关。使用该数据时,线程之间可能存在一些不一致,因为它不是线程安全的,但任何泄漏都不是使用静态而非正确多线程的结果。
您应该将依赖项传递到所需的位置,而不是全局访问。例如,使用全局变量的方法。通过参数将值传递给它。这称为依赖注入。
答案 2 :(得分:1)
关于内存泄漏的问题
我想先说这里没有内存泄漏问题。事实上,在两种情况下,它都与内存泄漏完全相反(它们在这方面是相同的)。对于DataHolder类,您只能有一个String实例(因为它是静态的,它不属于任何DataHolder实例)。
想象一下它不是静态的:
public class DataHolder
{
String dataString;
}
这意味着每次执行new DataHolder()
时,您将拥有一个单独的String实例。使用静态dataString,只会有一个实例。
获取和设置和同步
你的实施不好的原因是因为它不是线程安全的,正如Piyush Mittal指出的那样。虽然他没有详细说明,所以我想加两分钱。
你不能说这只是因为你只希望它在单个线程中使用,它只会在一个线程中使用。 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;
}
}
}
我确实更改了有关您代码的一些内容。第一个也是最明显的是没有这个关键字用于静态变量。正如我之前所暗示的,因为它的静态不属于任何实例。 '这'在静态环境中不是一件事。
我做的另一件事是把方法同步到内部。我这样做有两个原因。首先是偏好;有些人喜欢从函数签名中保持同步,因此它会被调用者混淆,因此他们不会做出假设,因为函数是同步的。这是偏好。我这样做的另一个原因是因为我想明确表示,当你在签名中同步一个函数时,这就是它实际上看起来的样子'。如上所述,由于没有'这个',它实际上会在类本身上同步。
我想你可能会使用一些关于static关键字的阅读。我认为你的困惑来自于你不理解它,并且在理解静态变量之前,你试图回答关于静态变量的getter和setter的问题。以下是我发现的快速谷歌搜索链接,可能会让您入门: http://www.javatpoint.com/static-keyword-in-java