web-dev-qa-db-ja.com

インターフェイスのすべてのフィールドが暗黙的に静的で最終的なのはなぜですか?

インターフェイスで定義されたすべてのフィールドが暗黙的にstaticfinalである理由を理解しようとしています。フィールドstaticを保持するという考えは、インターフェイスのオブジェクトを取得できないのに理にかなっていますが、なぜそれらがfinal(暗黙的に)なのでしょうか?

Javaデザイナーがインターフェイスstaticおよびfinal

92
peakit

インターフェースは、対話のコントラクトのみを指定し、実装の詳細を指定しないことを目的としているため、動作または状態を持つことはできません。メソッド/コンストラクターの本体または静的/インスタンスの初期化ブロックを許可しない場合、動作は強制されません。静的な最終フィールドのみを許可することで状態は強制されません。したがって、クラスは状態(静的状態)を持つことができますが、インスタンスの状態はインターフェースによって推論されません。

BTW:Javaの定数は、静的最終フィールドによって定義されます(慣習により、名前はUPPER_CASE_AND_UNDERSCORESを使用します)。

122
Adriaan Koster

finalである理由

フィールドが最終として定義されていない場合、どの実装でもフィールドの値を変更できます。その後、それらは実装の一部になります。インターフェイスは、実装のない純粋な仕様です。

staticである理由

それらが静的である場合、それらはオブジェクトにも、オブジェクトのランタイム型にもではなく、インターフェイスに属します。

26

ここにはいくつかのポイントがあります。

インターフェイスのフィールドが暗黙的に静的なfinalであるからといって、コンパイル時の定数である必要はなく、不変であることも意味しません。以下を定義できます。

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(アノテーション定義内でこれを行うと、上記が実際に静的イニシャライザにコンパイルされるという事実に関連して confc javac になる可能性があることに注意してください。)

また、この制限の理由は技術的なものよりも文体的であり、多くの人が リラックスしているように見たい です。

17
Jesse Glick

フィールドは(メソッドができるように)抽象化できないため、静的でなければなりません。抽象化できないため、実装者はフィールドの異なる実装を論理的に提供することはできません。

フィールドは多くの異なる実装者によってアクセスされる可能性があるため、フィールドは最終的なものでなければなりません(同期として)問題があるかもしれません。また、再実装(非表示)されないようにします。

ちょうど私の考え。

9
NawaMan

フィールドが不当に制限的であり、Java言語設計者による間違いであるため、フィールドが最終的なものであるという要件を考慮します。インターフェース型のオブジェクトで操作を実行する実装クラスでコードパスを選択するのは面倒です使用する回避策は、インターフェース関数を定義し、リテラルを返すことで実装することです:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

ただし、この構文を使用する方が簡単で、明確で、異常な実装が少ない傾向があります。

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}
2
Carl Klapper

仕様、契約...フィールドアクセスの機械命令は、オブジェクトアドレスとフィールドオフセットを使用します。クラスは多くのインターフェイスを実装できるため、このインターフェイスを拡張するすべてのクラスで同じ最終オフセットインターフェイスフィールドを作成する方法はありません。したがって、フィールドアクセスの異なるメカニズムを実装する必要があります。1つではなく2つのメモリアクセス(フィールドオフセットの取得、フィールド値の取得)に加えて、一種の仮想フィールドテーブル(仮想メソッドテーブルのアナログ)を維持します。既存のもの(メソッド)を介して簡単にシミュレートできる機能のためにjvmを複雑にしたくないだけだと思います。

scalaでは、インターフェイスにフィールドを含めることができますが、内部的には上記で説明したように(メソッドとして)実装されます。

0
Yaroslav