strictfp关键字在实现/扩展接口/类

时间:2016-08-31 16:27:18

标签: java extends implements strictfp

JLS strictfp Interfaces指定:

  

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

     

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

JLS strictfp Classes

  

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

     

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

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

搜索后,我找到了strictfp关键字Use the strictfp modifier for floating-point calculation consistency across platforms用法的一个很好的解释,它指定了:

  

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

它补充说: enter image description here

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

有人能解释strictfp在实现/扩展用strictfp修饰符声明的接口/类时的正确行为吗?

2 个答案:

答案 0 :(得分:8)

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

结论:

    strictfp接口中声明的
  1. 抽象方法在实现接口的类中不会是strictfp
  2. strictfp接口中声明的
  3. 默认方法将在实现接口的类中为stricfp
  4. 实施 strictfp接口的类中的方法不会自动为strictfp
  5. strictfp接口内部类中声明的所有方法都将具有stricfp修饰符
  6. 总结一下 - 如果在接口上声明了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
    

答案 1 :(得分:1)

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

  

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

     

当且仅当时,表达式不是FP-strict   不是一个恒定的表达式,它不会出现在中   声明,它具有strictfp修饰符。

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

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