Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write to a static field safely in Java?

say I had a class that creates objects and keeps track of the number of objects with a static variable. Something like this:

public class Apple {
    private static int count = 0;

    public Apple () {
        count++;
    } 

    public void removeApple() {
        count--;
    }
}

When I check this code with FindBugs I get the warning Write to static field from instance method, which is obvious of course.

How can I work around this problem and make it more safe and even get rid of that FindBugs Warning??

like image 510
user2426316 Avatar asked Dec 09 '22 14:12

user2426316


2 Answers

1. General programming advice

This message is there to warn you about a potential programming mistake because it is a common pitfall for beginner programmers, who are not aware of the differences in the scope of static and instance variables.

However, if you can declare your real version of the removeApple method static without causing any compiler errors, then most probably you should. This would both take care of the warning and make it clear that this method has nothing to do with any specific instance of your class.

2. Concerns related to concurrency

Another aspect of this warning concerns thread safety. If you write to a static field from an instance, that opens the possibility that you'll be doing concurrent updates from different threads, even with no sharing of the class instances between threads.

If you don't need thread safety for your code (which is perfectly fine in general), then you don't need to do anything. If you do need it, then synchronize all updates of the field, or use an AtomicInteger wrapper.

Personally, I'd opt for AtomicInteger because it's the safest option: other options would need you to chase all field updates around the class and make sure they are synchronized. Using AtomicInteger is very simple:

private static final AtomicInteger count = new AtomicInteger();

and then you use count.getAndIncrement() instead of count++.

like image 58
Marko Topolnik Avatar answered Dec 11 '22 03:12

Marko Topolnik


Use AtomicInteger instead of int primitive.

You might synchronize the method.

like image 25
duffymo Avatar answered Dec 11 '22 03:12

duffymo