繁体   English   中英

strictfp关键字在实现/扩展接口/类时的行为

[英]Behavior of strictfp keyword with implementing/extending an interface/class

JLS strictfp接口指定:

strictfp修饰符的作用是使接口声明中的所有float或double表达式都是显式FP-strict(第15.4节)。

这意味着在接口中声明的所有嵌套类型都是隐式strictfp。

JLS strictfp类

strictfp修饰符的作用是使接口声明中的所有float或double表达式都是显式FP-strict(第15.4节)。

这意味着在接口中声明的所有方法以及在接口中声明的所有嵌套类型都是隐式strictfp。

从这两段开始,没有任何迹象表明strictfp在实现/扩展使用strictfp修饰符声明的接口/类时的行为。

搜索后我发现了strictfp关键字用法的一个很好的解释使用strictfp修饰符来实现跨平台的浮点计算一致性 ,并指定:

扩展FP严格超类的子类不会继承严格的行为。 当重写方法不是时,重写方法可以独立地选择FP-strict,反之亦然。

并补充说: 在此输入图像描述

我测试了strictfp关键字的行为,同时扩展了用strictfp关键字声明的类,并且它是真的: strictfp行为不是由扩展类的类继承的,但问题是在实现用strictfp关键字声明的接口时它是不正确的: strictfp行为是不是由实现接口的类继承的。

任何人都可以通过实现/扩展使用strictfp修饰符声明的接口/类来解释strictfp的正确行为吗?

以下是我为调查您的问题所做的实验。 下面的代码使用了反射api来检查在各种情况下是否声明了strictfp

结论:

  1. strictfp接口中声明的抽象方法在实现接口的类中不是strictfp
  2. strictfp接口中声明的默认方法将是实现接口的类中的stricfp
  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

JLS§15.4非常清楚哪些表达式是FP严格的,哪些不是。

如果类,接口或方法X被声明为strictfp,那么X和X中的任何类,接口,方法,构造函数,实例初始化器,静态初始化器或变量初始化器都被认为是FP严格的。

因此, 当且仅当表达式不是常量表达式并且它不出现在具有strictfp修饰符的任何声明中时 ,表达式不是FP严格的

这里的关键字是声明 如果类声明中没有strictfp修饰符,则此类中的表达式将不是FP严格的,无论该类实现什么样的表面。

这符合您的观察结果。 从普通的观点来看,这听起来也是合理的; 否则,不可能从类的任何成员(包括新引入的成员)“重置”FP严格性。 查看javac或HotSpot JVM源代码,您将找不到strictfp继承的任何迹象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM