Как сделать (статический) блок инициализатора strictfp?
При рефакторинге некоторого кода я наткнулся на эту странность. Кажется невозможным управлять свойством strictfp для инициализатора, не затрагивая весь класс. Пример:
public class MyClass {
public final static float[] TABLE;
strictfp static { // this obviously doesn't compile
TABLE = new float[...];
// initialize table
}
public static float[] myMethod(float[] args) {
// do something with table and args
// note this methods should *not* be strictfp
}
}
Из JLS, раздел 8.1.1.3, я понял, что инициализатор был бы strictfp, если бы класс был объявлен с использованием модификатора strictfp. Но он также говорит, что делает все методы неявно строгими:
Эффект модификатора strictfp заключается в том, чтобы сделать все выражения с плавающей запятой или двойные выражения в объявлении класса (в том числе внутри инициализаторов переменных, инициализаторов экземпляров, статических инициализаторов и конструкторов) явным образом строгим по отношению к FP (§15.4).
Это подразумевает, что все методы, объявленные в классе, и все вложенные типы, объявленные в классе, являются неявно строгими.
Таким образом, модификатор не принимается для статического инициализатора, и когда он применяется ко всему классу, все становится строгим fp? Так как нет противоположного ключевому слову strictfp, этого невозможно достичь?
Итак, я прикручен, чтобы использовать статический метод, чтобы удерживать тело блока инициализатора для достижения точного контроля за соблюдением строгой производительности?
1 ответ
Используя требования, которые:
- код инициализации вызывается один раз,
-
MyClass.myMethod
метод не является строгим с плавающей точкой, - API класса не "замусорен" методами,
- и код инициализации строго с плавающей точкой
... этого будет достаточно
class MyClass {
//1) initialized/called once
public final static float[] TABLE = MyClassInitializer.buildSomething();
public static float[] myMethod(float[] args) {
//2) non-strict
}
}
//3) doesn't "pollute" the MyClass API
class MyClassInitializer {
strictfp [static] float[] buildSomething() { //4) strictfp here or on the class
//TODO: return something
}
}
Если вы рассматриваете статические члены класса как объекты в отдельном одноэлементном объекте, приведенный выше пример будет казаться естественным. Я думаю, что это очень хорошо сочетается с принципом единой ответственности.