Difference between using static fields using getter and setter and static fields declared public

I have been looking for the best data storage / exchange that will be used globally and as expected I found many answers. One way to get attention is by using static fields. However, the static field path listed here was as follows:

public class DataHolder
{
   private static String dataString;

   public static String getDataString
   {
      return dataString;
   }

   public static void setString(String dataString)
   {
      this.dataString = dataString;
   }
}

      

But I always do this:

public class DataHolder
{
   public static String dataString;
}

      

I'm just wondering, isn't the latter much easier than the former? Because I don't need to set any getter and setter methods. And I do not see the difference between them. So why not recommend the second one?

I was also told that this could lead to memory leak problems. But wouldn't the first solution lead to memory leak problems?

+3


source to share


3 answers


Your question is about memory leak

I want to start by saying that there will be no memory leak problems here. In fact, in both cases it would be the exact opposite of memory leaks (they are the same in this regard). You can only have one String instance per DataHolder class (since it is static, it does not belong to a DataHolder instance).

Imagine it was not static:

public class DataHolder
{
   String dataString;
}

      

this means that for each time you do new DataHolder()

, you will have a separate String instance. With your static dataString, there will only be one instance.

Getters, Setters and Synchronization

The reason your implementation is bad is because it is not thread safe, as noted by Piyush Mittal. However, he hasn't received any details, so I want to add my two cents.



You cannot say this just because you only expect it to be used on one thread, to be used on only one thread. The Swing thread is a great example of this, where there is only one thread that handles the UI. In this case, you would expect only one thread to exist, which is fine. However, any background work must be done on the SwingWorker thread, so creating a SwingWorker thread here to do this would provide a data race opportunity because there are now two threads. For this reason, you should always have getters and setters for static variables.

In this case, the given code snippet exactly matches between the two examples (with a slight difference in generating a new stack frame for a new function), since there is no synchronization. You want to do this:

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;
    }
  }
}

      

I have changed a few things about your code. The first and most obvious is the keyword used for static variables. As I hinted earlier, because its static it doesn't belong to any instance. 'this' is not part of the static context.

Another thing I did was sync within the method. I did this for two reasons. The first was preference; some people prefer to synchronize from the function signature, so it gets confused from the caller, so they don't make assumptions because the function is synchronized. This is a preference. Another reason I did this is because I wanted to make it obvious that when you sync a function in a signature, this is how it actually looks "under the hood." As mentioned, since there is no 'this', it actually syncs with the class itself.

I think you could probably read a little about the static keyword. I think your confusion comes from not understanding this and trying to answer the question about getters and setters for a static variable before digging into the statistics themselves. Here is the link I found with a quick google search that can get you started: http://www.javatpoint.com/static-keyword-in-java

+1


source


Hope you have a lot of ideas about memory leaks.



But: multiple concurrent requests - multiple threads, you most likely have a threading problem - it's not thread safe unless you take care (use synchronized for example ) ..

+1


source


I would prefer to use getter / setters over a public field.

This type of encapsulation allows you to change property types without breaking the code of those who use it.

What if you decide to create a type Data

rather than store it as String

? (to improve security by type).

This is not possible with a public field. But using getter / setters you can parse to resolve this:

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;
    }
}

      

This is not a memory leak problem as it has nothing to do with memory allocation. While using this data, there may be some inconsistency between threads because it is not thread safe, but any leaks will not be the result of using static rather than multithreading control.

Rather than referring to anything globally, you should pass the dependency where it is needed. For example, a method that uses a global variable. Pass the value through parameters. This is called dependency injection.

+1


source







All Articles