Поведение ключевого слова strictfp с реализацией / расширением интерфейса / класса
JLS strictfp Interfaces указывает, что:
Эффект модификатора strictfp заключается в том, чтобы сделать все выражения с плавающей запятой или двойные выражения в объявлении интерфейса строго FP-строгими (§15.4).
Это подразумевает, что все вложенные типы, объявленные в интерфейсе, неявно строгие.
Эффект модификатора strictfp заключается в том, чтобы сделать все выражения с плавающей запятой или двойные выражения в объявлении интерфейса строго FP-строгими (§15.4).
Это подразумевает, что все методы, объявленные в интерфейсе, и все вложенные типы, объявленные в интерфейсе, являются неявно строгими.
Из этих двух параграфов нет никаких признаков поведения strictfp
при реализации / расширении интерфейса / класса, объявленного с strictfp
модификатор.
После поиска я нашел хорошее объяснение использования strictfp
Ключевое слово Используйте модификатор strictfp для согласованности вычислений с плавающей точкой на разных платформах, и он указывает, что:
Строгое поведение не наследуется подклассом, который расширяет суперкласс строгого FP. Переопределяющий метод может независимо выбрать строгий FP, если переопределяемый метод - нет, или наоборот.
Я проверил поведение strictfp
Ключевое слово при расширении класса объявлено с strictfp
Ключевое слово, и это правда: strictfp
поведение не наследуется классами, расширяющими класс, но проблема заключается в реализации интерфейса, объявленного с strictfp
Ключевое слово это не правильно: strictfp
поведение не наследуется классами, реализующими интерфейс.
Может ли кто-нибудь объяснить мне правильное поведение strictfp
с реализацией / расширением интерфейса / класса, объявленного с strictfp
модификатор?
2 ответа
Вот эксперименты, которые я сделал, чтобы исследовать ваш вопрос. Код ниже использует отражения API, чтобы проверить, strictfp
заявлено или нет в различных сценариях.
Выводы:
- Абстрактные методы, объявленные в интерфейсе strictfp, не будут строгими в классе, реализующем интерфейс
- Методы поумолчанию, объявленные в интерфейсе strictfp, будут stricfp в классе, реализующем интерфейс
- Методы в классах, которые реализуют интерфейс strictfp, не будут автоматически подвергаться strictfp
- Все методы, объявленные во внутренних классах интерфейса 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);
}
}
}
Вывод программы: (используя jdk1.8.0_91.jdk на OSX)
someInterfaceMethod modifiers: public
someClassMethod modifiers: public strictfp
someClassMethod2 modifiers: public
someInterfaceDefaultMethod modifiers: public strictfp
innerMethod modifiers: public static strictfp
В JLS §15.4 довольно ясно, какие выражения строго FP, а какие нет.
Если класс, интерфейс или метод, X, объявлен строгим fp, то X и любой класс, интерфейс, метод, конструктор, инициализатор экземпляра, статический инициализатор или инициализатор переменной в X называются FP-строгими.
Из этого следует, что выражение не является FP-строгим в том и только в том случае, если оно не является константным выражением и не отображается ни в одном объявлении, которое имеет модификатор strictfp.
Ключевое слово здесь - декларация. Если нет strictfp
Модификатор в объявлении класса, выражения в этом классе не будут строго FP, независимо от того, какие интерфейсы реализует этот класс.
Это соответствует вашим наблюдениям. Это также звучит разумно из здравого смысла; в противном случае было бы невозможно "сбросить" строгость FP для любого члена класса, включая вновь представленных членов. Смотря на javac
или исходный код HotSpot JVM вы не найдете никаких признаков strictfp
наследование.