在实例方法中写入静态变量,为什么这是一个不好的做法?

Osc*_*mez 17 java methods static instance

我在这里用eclipse中的这个findbugs警告有点困惑.

public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       MyClass.myString = "something";
   }
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个findbugs警告"从实例方法写入静态字段",但这并没有给我一个警告:

public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       doAnotherThing();
   }
   public static doAnotherThing() {
       MyClass.myString = "something";
   }
}
Run Code Online (Sandbox Code Playgroud)

这有什么不同?,为什么从实例方法写入静态变量是一种不好的做法?我认为它与同步有关,但我仍然不清楚.

我知道这看起来变量应该是final,但我从属性文件加载值.

Ber*_*t F 18

它是一种混叠形式,可能违反直觉.反直觉代码妨碍了易于维护.

从逻辑上讲,我们希望实例方法能够影响该实例的数据.我们期望静态方法影响静态数据.

让我们重命名doSomethinginitialize:

...
a.initialize();
...
b.initialize();
...
Run Code Online (Sandbox Code Playgroud)

此代码的读者可能无法立即意识到实例a并且b实际上正在影响相同的数据.这可能是一个错误,因为我们两次初始化相同的内存,但它不明显,因为我们可能需要调用initialize每个实例似乎是合理的.

但是,代码是:

...
MyClass.initialize();
...
MyClass.initialize();
...
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它更直观,我们可能会影响相同的静态数据,这可能是一个错误.

这类似于别名的通用版本,其中同一范围内的两个变量指向同一实例.


对于你的上一个例子,

  • 实例调用静态方法

    实例方法调用静态方法的事实不会引发标志.这个例子很有用,远远超过可能存在问题的地方.

  • 一个类的静态方法会影响另一个类的静态数据

    从某种意义上说,它应该生成一个不同但相似的警告:一个类正在弄乱另一个类的数据.但是,通过使静态变量公开是一种默认的方式,所以不需要这样的警告.

请记住,FindBugs只是试图在代码中标记潜在的可能问题,而不是每个可能的问题.您的第一个示例可能是一个潜在的维护问题,您需要检查它是否是一个真正的问题.你的第二个例子可能不是问题,或者它是一个真正的问题,它与没有问题的用例过于相似.