java - together - Comportamiento de la palabra clave strictfp con la implementación/extensión de una interfaz/clase
java public class extends (2)
JLS strictfp Interfaces especifica que:
El efecto del modificador strictfp es hacer que todas las expresiones flotantes o dobles dentro de la declaración de interfaz sean explícitamente FP-estrictas (§15.4).
Esto implica que todos los tipos anidados declarados en la interfaz son implícitamente estrictos.
El efecto del modificador strictfp es hacer que todas las expresiones flotantes o dobles dentro de la declaración de interfaz sean explícitamente FP-estrictas (§15.4).
Esto implica que todos los métodos declarados en la interfaz, y todos los tipos anidados declarados en la interfaz, son implícitamente estrictos.
De esos dos párrafos, no hay ninguna indicación del comportamiento de strictfp
al implementar / extender una interfaz / clase declarada con el modificador de strictfp
.
Después de buscar encontré una buena explicación del uso de la palabra clave strictfp
Use el modificador strictfp para la consistencia del cálculo de punto flotante en todas las plataformas , y especifica que:
El comportamiento estricto no es heredado por una subclase que extiende una superclase estricta de FP. Un método de anulación puede elegir independientemente ser estricto de FP cuando el método anulado no lo es, o viceversa.
strictfp
el comportamiento de la palabra clave strictfp
mientras extendía la clase declarada con la palabra clave strictfp
y es cierto: el comportamiento strictfp
no es heredado por las clases que extienden la clase, pero el problema es que al implementar una interfaz declarada con la palabra clave strictfp
no es correcto: No heredado por las clases que implementan la interfaz.
¿Puede alguien explicarme el comportamiento correcto de strictfp
con la implementación / extensión de una interfaz / clase declarada con el modificador de strictfp
?
Aquí están los experimentos que hice para investigar tu pregunta. El código a continuación utiliza la api de reflexiones para verificar si el strictfp
está declarado o no en varios escenarios.
Conclusiones:
- Los métodos abstractos declarados en la interfaz strictfp no serán estrictamente en la clase que implementa la interfaz.
- Los métodos predeterminados declarados en la interfaz strictfp serán stricfp en la clase que implementa la interfaz
- Los métodos en las clases que implementan la interfaz strictfp no serán automáticamente strictfp
- Todos los métodos declarados en las clases internas de la interfaz strictfp tendrán el modificador stricfp
En resumen, si se declara strictfp
en la interfaz, entonces todos los códigos no abstractos (métodos predeterminados, clases internas con métodos) son automáticamente strictfp
.
Tenga en cuenta que el modificador strictfp
no se aplica a los métodos abstractos.
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);
}
}
}
La salida del programa: (usando jdk1.8.0_91.jdk en OSX)
someInterfaceMethod modifiers: public
someClassMethod modifiers: public strictfp
someClassMethod2 modifiers: public
someInterfaceDefaultMethod modifiers: public strictfp
innerMethod modifiers: public static strictfp
JLS §15.4 es bastante claro sobre qué expresiones son estrictas de FP y cuáles no.
Si una clase, interfaz o método, X, se declara estrictamente estricta, entonces X y cualquier clase, interfaz, método, constructor, inicializador de instancia, inicializador estático o inicializador de variable dentro de X se dice que es FP-strict.
De ello se deduce que una expresión no es FP-strict si y solo si no es una expresión constante y no aparece en ninguna declaración que tenga el modificador strictfp.
La palabra clave aquí es declaración . Si no hay strictfp
modificador strictfp
en una declaración de clase, las expresiones dentro de esta clase no serán estrictas de FP, independientemente de las interfaces que implemente esta clase.
Esto corresponde a tus observaciones. Esto también suena razonable desde el punto de vista común; de lo contrario, sería imposible "restablecer" la rigidez de FP de cualquier miembro de una clase, incluidos los miembros recién introducidos. Mirando el código fuente de javac
o HotSpot JVM, no encontrará ningún signo de herencia strictfp
.