1. ホーム
  2. java

[解決済み] なぜJavaでprotected staticを使用してはいけないのか?

2022-06-27 08:13:02

疑問点

私はこのような質問をしました。 Javaでクラス変数をオーバーライドする方法はありますか? というコメントがあり、36のアップヴォートを獲得しました。

もし、あなたが protected static を見たら、走ってください。

誰か説明してください。 protected static が嫌われる理由を説明できる人はいますか?

どのように解決するのですか?

直接的な問題というより、文体的なものです。クラスで何が起こっているのかをきちんと考えていないことを示唆しています。

を考えてみてください。 static の意味を考えてみてください。

この変数はクラスレベルで存在し、各インスタンスに個別に存在するわけではありませんし を拡張するクラスでは独立した存在にはなりません。 .

何を考えるか protected の意味を考えてみてください。

この変数は、このクラス、同じパッケージのクラスから見ることができます および私を拡張したクラス .

この2つの意味は正確には相反するものではありませんが、かなり近いものがあります。

この 2 つを一緒に使うことができる唯一のケースは、拡張されるように設計された抽象クラスがあり、拡張クラスが元のクラスで定義された定数を使用して動作を変更できる場合です。このような配置は、ほとんどの場合、非常に面倒なことになり、クラスの設計の弱点を示すことになります。

ほとんどの場合、定数をパブリックにしたほうがよいでしょう。抽象クラスが継承を強制する一方で、多くの場合、合成は継承よりも望ましいのです。

これがどのように物事を壊しうるかの一例と、変数が独立した存在でないことが何を意味するかを説明するために、次のサンプルコードを試してみてください。

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

クラス Test2 は、静的メンバ test から Test から、名前を修飾することなく、を継承しています。これは、メモリ内のまったく同じオブジェクトを見ているのです。