Как сделать (статический) блок инициализатора 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
  }
}

Если вы рассматриваете статические члены класса как объекты в отдельном одноэлементном объекте, приведенный выше пример будет казаться естественным. Я думаю, что это очень хорошо сочетается с принципом единой ответственности.

Другие вопросы по тегам