为什么我们不应该在java中使用受保护的静态

2022-08-31 08:12:24

我正在经历这个问题 有没有办法在Java中覆盖类变量?第一个获得36票的评论是:

如果您看到 ,请运行。protected static

谁能解释一下为什么一个不受欢迎?protected static


答案 1

这与其说是一个直接的问题,不如说是一个文体上的事情。这表明你还没有正确地思考这门课发生了什么。

想想这意味着什么:static

这个变量存在于类级别,它不是为每个实例单独存在的,并且在扩展我的类中没有独立的存在

想想这意味着什么:protected

这个变量可以通过这个类,同一包中的类和扩展我的类来查看。

这两种含义并不完全相互排斥,但它非常接近。

我能看到你可以同时使用这两者的唯一情况是,如果你有一个旨在扩展的抽象类,然后扩展类可以使用原始定义中的常量修改行为。这种安排很可能最终会变得非常混乱,并表明类设计中的弱点。

在大多数情况下,最好将常量作为公共常量,因为这只会使一切更干净,并允许人们子类化更大的灵活性。在许多情况下,除了其他任何东西之外,组合比继承更可取,而抽象类则强制继承。

要查看一个示例,说明这如何破坏事物,并说明我所说的变量没有独立存在的含义,请尝试以下示例代码:

public class Program {
    public static void main (String[] args) throws java.lang.Exception {
        System.out.println(new Test2().getTest());
        Test.test = "changed";
        System.out.println(new Test2().getTest());
    }
}

abstract class Test {
    protected static String test = "test";
}

class Test2 extends Test {
    public String getTest() {
        return test;
    }
}

您将看到结果:

test
changed

亲自尝试: https://ideone.com/KM8u8O

该类能够从中访问静态成员,而无需限定名称 - 但它不会继承或获取自己的副本。它正在查看内存中完全相同的对象。Test2testTest


答案 2

它令人不快,因为它是矛盾的。

创建变量意味着它将在包中使用,或者它将在子类中继承protected

使变量成为类的成员,从而消除了继承它的意图。这只留下了在包中使用的意图,我们有(没有修饰符)。staticpackage-private

我能发现的唯一有用的情况是,如果您要声明一个应该用于启动应用程序的类(如JavaFX的,并且只希望能够从子类启动。如果这样做,请确保该方法也不允许隐藏。但这不是“常态”,可能是为了防止通过添加启动应用程序的新方法来增加复杂性。Application#launchfinal

要查看每个修饰符的访问级别,请参阅以下内容:Java 教程 - 控制对类成员的访问