JLS strictfp Interfaces specifies that :
The effect of the strictfp modifier is to make all float or double expressions within the interface declaration be explicitly FP-strict (§15.4).
This implies that all nested types declared in the interface are implicitly strictfp.
And JLS strictfp Classes :
The effect of the strictfp modifier is to make all float or double expressions within the interface declaration be explicitly FP-strict (§15.4).
This implies that all methods declared in the interface, and all nested types declared in the interface, are implicitly strictfp.
From those two paragraphs there is no indication of the behavior of strictfp
while implementing/extending an interface/class declared with strictfp
modifier.
After searching I found a good explanation of the usage of strictfp
keyword Use the strictfp modifier for floating-point calculation consistency across platforms, and it specifies that :
Strict behavior is not inherited by a subclass that extends a FP-strict superclass. An overriding method can independently choose to be FP-strict when the overridden method is not, or vice versa.
And it adds :
I tested the behavior of strictfp
keyword while extending class declared with strictfp
keyword and it's true : the strictfp
behavior is not inherited by classes extending the class, but the problem is while implementing an interface declared with strictfp
keyword it's not correct : the strictfp
behavior is not inherited by classes implementing the interface.
Can anyone explain me the correct behavior of strictfp
with implementing/extending an interface/class declared with strictfp
modifier ?
strictfp is used to ensure that floating points operations give the same result on any platform. As floating points precision may vary from one platform to another. strictfp keyword ensures the consistency across the platforms.
In Java, floating point representations and computations are platform dependent. strictfp modifier ensures that all floating-point operations across different JVMs and platforms will provide consistent and same result predicted by IEEE 754.
When a class or an interface is declared with strictfp modifier, then all methods declared in the class/interface, and all nested types declared in the class, are implicitly strictfp. strictfp cannot be used with abstract methods. However, it can be used with abstract classes/interfaces.
'strictfp' keyword is used to force the precision of floating point calculations (float or double) in Java conform to IEEE's 754 standard, explicitly.
Here are the experiments I did to investigate your question. The code below uses reflections api to check if the strictfp
is declared or not in various scenarios.
Conclusions:
To sum it up - if the strictfp
is declared on the interface, then all the non-abstract code - default methods, inner classes with methods - are automatically strictfp
.
Please note that the strictfp
modifier is not applied to the abstract methods.
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);
}
}
}
The output of the program: (using jdk1.8.0_91.jdk on OSX)
someInterfaceMethod modifiers: public
someClassMethod modifiers: public strictfp
someClassMethod2 modifiers: public
someInterfaceDefaultMethod modifiers: public strictfp
innerMethod modifiers: public static strictfp
JLS §15.4 is pretty clear about which expressions are FP-strict, and which are not.
If a class, interface, or method, X, is declared strictfp, then X and any class, interface, method, constructor, instance initializer, static initializer, or variable initializer within X is said to be FP-strict.
It follows that an expression is not FP-strict if and only if it is not a constant expression and it does not appear within any declaration that has the strictfp modifier.
The keyword here is declaration. If there is no strictfp
modifier in a class declaration, the expressions within this class will not be FP-strict, no matter what iterfaces this class implements.
This corresponds to your observations. This also sounds reasonable from the common sence; otherwise it would be impossible to 'reset' FP-strictness from any member of a class, including newly introduced members. Looking at javac
or HotSpot JVM source code you won't find any sign of strictfp
inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With