Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of strictfp keyword with implementing/extending an interface/class

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 : enter image description here

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 ?

like image 799
Naruto Biju Mode Avatar asked Aug 31 '16 16:08

Naruto Biju Mode


People also ask

What does strictfp keyword mean in Java?

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.

Do you know strictfp modifier?

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.

How do I use strictfp?

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.

Which of the following techniques can be used to ensure that code in a Java SE class conforms to the IEEE 754 standard for floating point calculations?

'strictfp' keyword is used to force the precision of floating point calculations (float or double) in Java conform to IEEE's 754 standard, explicitly.


2 Answers

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:

  1. Abstract methods declared in strictfp interface will not be strictfp in the class implementing the interface
  2. Default methods declared in strictfp interface will be stricfp in the class implementing the interface
  3. Methods in classes that are implementing the strictfp interface will not be automatically strictfp
  4. All the methods declared in the inner classes of strictfp interface will have the stricfp modifier

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
like image 190
Piotr Reszke Avatar answered Nov 10 '22 00:11

Piotr Reszke


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.

like image 45
apangin Avatar answered Nov 09 '22 23:11

apangin