18

JLS strictfp インターフェイスでは、次のことが指定されています。

strictfp 修飾子の効果は、インターフェイス宣言内のすべての float または double 式を明示的に FP-strict にすることです (§15.4)。

これは、インターフェイスで宣言されたすべてのネストされた型が暗黙的に strictfp であることを意味します。

JLS strictfp クラス:

strictfp 修飾子の効果は、インターフェイス宣言内のすべての float または double 式を明示的に FP-strict にすることです (§15.4)。

これは、インターフェイスで宣言されたすべてのメソッド、およびインターフェイスで宣言されたすべてのネストされた型が暗黙的に strictfp であることを意味します。

これらの 2 つの段落からは、修飾子strictfpで宣言されたインターフェイス/クラスを実装/拡張している間の動作の兆候はありません。strictfp

strictfp検索した後、キーワードUse the strictfp modifier for floating-point scaling across platformsの使用法に関する適切な説明が見つかりました。

厳密な動作は、FP 厳密なスーパークラスを拡張するサブクラスには継承されません。オーバーライドされたメソッドがそうでない場合、オーバーライドするメソッドは独立して FP 厳密であることを選択できます。

そしてそれは追加します: ここに画像の説明を入力

strictfpキーワードで宣言されたクラスを拡張しているときにキーワードの動作をテストしましたがstrictfp、それは本当です:strictfp動作はクラスを拡張するクラスによって継承されませんが、問題はstrictfpキーワードで宣言されたインターフェイスを実装しているときに正しくありません:strictfp動作は実装するクラスによって継承されませんインターフェイス。

修飾子strictfpで宣言されたインターフェイス/クラスを実装/拡張する際の正しい動作を誰かが説明してくれますか?strictfp

4

2 に答える 2

9

あなたの質問を調査するために私が行った実験は次のとおりです。以下のコードは、リフレクション API を使用してstrictfp、さまざまなシナリオで が宣言されているかどうかを確認します。

結論:

  1. strictfp インターフェースで宣言された抽象メソッドは、インターフェースを実装するクラスでは strictfp になりません
  2. strictfp インターフェースで宣言されたデフォルトのメソッドは、インターフェースを実装するクラスではstrictfp になります
  3. strictfp インターフェースを実装しているクラスのメソッドは、自動的に strictfp になりません
  4. strictfp インターフェースの内部クラスで宣言されたすべてのメソッドには、stricfp 修飾子があります。

要約するとstrictfp、インターフェイスで が宣言されている場合、すべての非抽象コード (デフォルト メソッド、メソッドを持つ内部クラス) は自動的に になりますstrictfp

strictfp修飾子は抽象メソッドには適用されないことに注意してください。

import java.lang.reflect.Modifier;

strictfp interface StrictInterface {

    void someInterfaceMethod();

    default void someInterfaceDefaultMethod() {}

    class InnerTest {
        public static void innerMethod() {}
    }
}

class Impl implements StrictInterface {
    @Override
    public void someInterfaceMethod() {}

    public strictfp void someClassMethod() {}

    public void someClassMethod2() {}
}

public class Test {
    public static void main(String argv[]) {

        checkModifiers(Impl.class, "someInterfaceMethod");
        checkModifiers(Impl.class, "someClassMethod");
        checkModifiers(Impl.class, "someClassMethod2");

        checkModifiers(Impl.class.getInterfaces()[0], "someInterfaceDefaultMethod");
        checkModifiers(StrictInterface.InnerTest.class, "innerMethod");
    }
    public static void checkModifiers(Class clazz, String m) {
        try {
            int mod = clazz.getDeclaredMethod(m, new Class[0]).getModifiers();
            String res = m + " modifiers: " + Modifier.toString(mod);
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }
}

プログラムの出力: (OSX で jdk1.8.0_91.jdk を使用)

someInterfaceMethod modifiers: public
someClassMethod modifiers: public strictfp
someClassMethod2 modifiers: public
someInterfaceDefaultMethod modifiers: public strictfp
innerMethod modifiers: public static strictfp
于 2016-09-19T11:29:02.457 に答える
1

JLS §15.4は、どの式が FP 厳密であり、どの式がそうでないかについてかなり明確です。

クラス、インターフェース、またはメソッド X が strictfp と宣言されている場合、X および X 内の任意のクラス、インターフェース、メソッド、コンストラクター、インスタンス初期化子、静的初期化子、または変数初期化子は、FP-strict であると言われます。

したがって、式が定数式ではなく、strictfp 修飾子を持つ宣言内に現れない場合に限り、その式は FP 厳密ではありません。

ここでのキーワードは宣言です。クラス宣言strictfpに修飾子がない場合、このクラスが実装する iterface に関係なく、このクラス内の式は FP 厳密ではありません。

これはあなたの観察に対応しています。これは、常識から見ても合理的に聞こえます。そうしないと、新しく導入されたメンバーを含む、クラスのメンバーから FP 厳密性を「リセット」することができなくなります。またはHotSpot JVMソースコードを見ると、継承javacの兆候は見つかりません。strictfp

于 2016-09-20T08:34:25.523 に答える