[英]Behavior of strictfp keyword with implementing/extending an interface/class
strictfp修饰符的作用是使接口声明中的所有float或double表达式都是显式FP-strict(第15.4节)。
这意味着在接口中声明的所有嵌套类型都是隐式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
。
结论:
总结一下 - 如果在接口上声明了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.