- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我搜索了保存/共享将在全局范围内使用的数据的最佳方式,正如预期的那样,我找到了很多答案。引起我注意的方法之一是使用静态字段。然而,静态字段的方式是这样的:
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 方法。而且我看不出两者有什么区别。那么为什么不推荐第二个呢?
我之前也被告知按照我的方式有时会导致内存泄漏问题。但是第一个解决方案不会导致内存泄漏问题吗?
最佳答案
关于内存泄漏的问题
首先我想说这里不会有内存泄漏问题。事实上,这两种情况都与内存泄漏完全相反(在这方面它们是相同的)。 DataHolder 类只能有一个 String 实例(因为它是静态的,它不属于任何 DataHolder 实例)。
假设它不是静态的:
public class DataHolder
{
String dataString;
}
这意味着每次执行 new DataHolder()
时,您都会有一个单独的 String 实例。使用静态数据字符串,将永远只有一个实例。
Getters 和 Setters 以及同步
正如 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;
}
}
}
我确实更改了您的代码的一些内容。第一个也是最明显的是没有用于静态变量的 this 关键字。正如我之前暗示的那样,因为它是静态的,所以它不属于任何实例。 “this”不是静态上下文中的事物。
我做的另一件事是将 synchronized 放在方法中。我这样做有两个原因。首先是偏好;有些人更喜欢在函数签名之外保持同步,这样它就被调用者混淆了,所以他们不做假设,因为函数是同步的。那就是偏好。我这样做的另一个原因是因为我想让它很明显,当你在签名中同步一个函数时,这就是它在“幕后”的实际样子。如前所述,由于没有“this”,它实际上会在类本身上进行同步。
我认为您可能需要阅读一些有关 static 关键字的资料。我认为您的困惑来自您不理解它的事实,并且您试图在理解静态本身之前回答有关静态变量的 getter 和 setter 的问题。这是我通过快速谷歌搜索找到的链接,可以帮助您入门: http://www.javatpoint.com/static-keyword-in-java
关于java - 使用使用 getter 和 setter 的静态字段与声明为公共(public)的静态字段之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31896094/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
在 C# 静态方法中是否有一种方法可以引用定义该方法的类型? 在实例方法中,您可以通过以下方式确定类型: public void Foo() { Type type = this.GetTyp
WPF:静态、动态资源以及资源词典 静态资源与动态资源 我们常常会使用样式或者控件模板放在Window.Resources中,比如这样: 静态资源与动态资源使用如下: <Window
任何人都知道如何在共享/静态函数中动态加载控件?该函数本身位于 mustinherit/abstract 类中。 (这是 VB 中的 ASP.NET 项目)我想做这样的事情: VB: Publ
在我看来,静态/强类型编程语言最宝贵的一点是它有助于重构:如果/当您更改任何 API,那么编译器会告诉您该更改破坏了什么。 我可以想象用运行时/弱类型语言编写代码......但我无法想象没有编译器的帮
正如我的名字所暗示的,我是一名 .NET 开发人员,但我对 Java 的兴趣越来越大,并且我有兴趣学习更多其他语言,因为这有助于我学习更多关于编程的知识。 无论如何,我的问题是:不带参数/不使用状态的
我在java中使用WireMock来 stub POST请求。该请求返回一个存储在我本地的 json 正文文件。 stub 看起来像这样: wireMockServer.stubFor(get(url
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
这个问题已经有答案了: What is the difference between dynamic and static polymorphism in Java? (14 个回答) 已关闭 4 年
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Static initializer in Java 我想知道这个静态的东西(抱歉,这是我第一次遇到这个)对一个类有
如果c++应用程序是按以下方式组织的 //file1.cpp static Y sgObj = X::getInitObject(0); //declared in file scope //fil
我有一个抽象类(AvergedDataRecord),我需要进一步抽象(DataRecord),这样我就可以将它扩展到原始类和一个新的具体类(SummedDataRecord),并且我在获取某些方法时
我正在尝试制作一个字符串枚举。这是我到目前为止所得到的, private class TypedEnum : IEnumerable { public IEnumerator GetEnume
我选修了一门名为“安全代码”的类(class),在下一个作业中,我们应该对一些 C 文件和 JavaEE Web 项目进行静态/动态分析。 我检查了“源监视器”并在 C 文件上运行它,但是(除非我不知
我有两个类,一个是登录类,一个是用户类。在 loggedIn 类中,我想显示我在用户登录时所做的共享首选项。 loginPrefs = getSharedPreferences("loginprefe
我在同一个 Activity 中有两个静态 fragment ,在“fragmentA”中我有一个自定义列表,当一个项目被点击时必须在“fragmentB”中出现一个细节,细节只在我改变屏幕方向时出现
在 Java 中是未修改方法变量,缺少final,每次都重新初始化限定符 静态方法 实例方法 如果 1. 或 2.(或两者)的答案是 final 限定符允许 Java 执行优化并存储方法变量只有一次?
我有两个类相互交互。第一个是中心的,如下: public class Datenbank { double winkelPanel = 0; double groessePanel = 0; doub
我有一个 mysql 数据库,它连接基于 Web 的 php 应用程序和 FoxPro 应用程序(是的,foxpro)。在之前的“开发人员”被解雇后开始处理这个问题。 无论如何,我熟悉 AES_Enc
我是一名优秀的程序员,十分优秀!