Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing to a static variable in an instance method, why is this a bad practice?

I am a little confused here with this findbugs warning in eclipse.

public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       MyClass.myString = "something";
   }
}

This gives me a findbugs warning "write to static field from instance method", however this does not give me a warning:

public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       doAnotherThing();
   }
   public static doAnotherThing() {
       MyClass.myString = "something";
   }
}

How is this any different?, and why is writing to a static variable from an instance method a bad practice?, I assume it has to do with synchronization, but it is still not clear to me.

I know this looks like the variable should be final, but I am loading the value from a properties file.

like image 674
Oscar Gomez Avatar asked Feb 01 '11 23:02

Oscar Gomez


People also ask

Is it bad practice to use static variables?

Static variables are generally considered bad because they represent global state and are therefore much more difficult to reason about. In particular, they break the assumptions of object-oriented programming.

Why static methods are bad?

Static methods are bad for testability.Since static methods belong to the class and not a particular instance, mocking them becomes difficult and dangerous. Overriding a static method is not that simple for some languages.

Can we use static For instance variable?

We cannot directly access the instance variables within a static method because a static method can only access static variables or static methods. An instance variable, as the name suggests is tied to an instance of a class.


4 Answers

Its a form of aliasing, which may be counter-intuitive. Counter-intuitive code hampers ease of maintenance.

Logically, we expect instance methods to affect that instance's data. We expect static methods to affect static data.

Let's rename doSomething to initialize:

...
a.initialize();
...
b.initialize();
...

The reader of this code may not immediately realize that the instances of a and b are actually affecting the same data. This may be a bug since we're initializing the same memory twice, but its non-obvious since it seems reasonable that we may need to call initialize on each instance.

However, the the code were:

...
MyClass.initialize();
...
MyClass.initialize();
...

In this case, its more intuitive that we're likely affecting the same static data and this is likely a bug.

This is similar to the common version of aliasing where two variables in the same scope point to the same instance.


For your last example,

  • an instance calls a static method

    The fact that an instance method is calling a static method isn't expected to raise flags. The examples were this is useful far outweigh where its likely a problem.

  • a static method of one class affects another class' static data

    In one sense, it should generate a different, but similar warning: that one class is messing with the data of another class. However, by making the static variable public is a way of tacitly approving of this, so such a warning isn't necessary.

Keep in mind that FindBugs is simply trying to flag potential likely problems, not every possible problem, in your code. Your first example is likely a potential maintenance issue that you need to examine whether its a real problem. Your second example is likely not a problem or it is a real problem that is too similar to use cases where it is not a problem.

like image 62
Bert F Avatar answered Oct 07 '22 14:10

Bert F


There aren't many use cases for why you would want to change a static field. Remember that if you set this field to a new value that this value has changed for all instances of this class. This might get you into trouble in a multi-threaded environment, where more than one thread is calling doSomething(). Proper synchronisation is required.

In 99% of all cases, you want your instance methods to change the non-static fields only, which is why findbugs warns you.

And findbugs isn't clever enough to find out about your instance method indirectly changing the field in your second example :)

like image 31
Jochen Bedersdorfer Avatar answered Oct 07 '22 13:10

Jochen Bedersdorfer


This is what FindBugs has to say about this: http://findbugs.sourceforge.net/bugDescriptions.html#ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD

like image 3
Costi Ciudatu Avatar answered Oct 07 '22 14:10

Costi Ciudatu


This is my take, so take it with a grain of salt. You mentioned synchronization issues, which are a major reason for this warning, but more importantly, the two cases are fundamentally operating on different conceptual "levels" of data. Instance methods are "owned" by objects and modify data that describes individual instances. Class methods are generic operations and state that, while related to the class, are not related to individual objects. Thus, modifying that state from within each instance would probably (but not necessarily) be a poor design decision.

like image 1
yan Avatar answered Oct 07 '22 13:10

yan