java - usar - Argumentos finales en métodos de interfaz: ¿cuál es el punto?
jframe en java (5)
En Java, es perfectamente legal definir argumentos final
en métodos de interfaz y no obedecer eso en la clase implementadora, por ejemplo:
public interface Foo {
public void foo(int bar, final int baz);
}
public class FooImpl implements Foo {
@Override
public void foo(final int bar, int baz) {
...
}
}
En el ejemplo anterior, bar
y baz
tiene las definiciones final
opuestas en la clase VS de la interfaz.
De la misma manera, no se aplican restricciones final
cuando un método de clase se extiende a otro, ya sea abstract
o no.
Mientras que el valor final
tiene algún valor práctico dentro del cuerpo del método de clase, ¿hay algún punto que especifique el final
para los parámetros del método de interfaz?
Algunos IDEs copiarán la firma del método abstracto / interfaz al insertar un método de implementación en una subclase.
No creo que haga ninguna diferencia para el compilador.
Creo que puede ser un detalle superfluo, ya sea si es definitivo o no, es un detalle de implementación.
(Algo así como declarar métodos / miembros en una interfaz como públicos).
Las anotaciones finales de los parámetros del método siempre son solo relevantes para la implementación del método, nunca para la persona que llama. Por lo tanto, no hay una razón real para usarlos en las firmas de métodos de interfaz. A menos que desee seguir el mismo estándar de codificación consistente, que requiere parámetros de método finales, en todas las firmas de métodos. Entonces es bueno poder hacerlo.
No parece que sea así. De acuerdo con la Especificación del lenguaje Java 4.12.4 :
Declarar una variable final puede servir como documentación útil de que su valor no cambiará y puede ayudar a evitar errores de programación.
Sin embargo, un modificador final
en un parámetro de método no se menciona en las reglas para hacer coincidir firmas de métodos reemplazados, y no tiene ningún efecto en el llamador, solo dentro del cuerpo de una implementación. Además, como observó Robin en un comentario, el modificador final
en un parámetro de método no tiene efecto en el código de bytes generado. (Esto no es cierto para otros usos de final
).
Actualización: la respuesta original a continuación fue escrita sin entender completamente la pregunta, y por lo tanto no aborda directamente la pregunta :)
Sin embargo, debe ser informativo para aquellos que buscan entender el uso general de final
palabra clave final
.
En cuanto a la pregunta, me gustaría citar mi propio comentario de abajo.
Creo que no estás obligado a implementar la finalidad de un argumento para dejarte libre para decidir si debe ser final o no en tu propia implementación.
Pero sí, parece bastante extraño que puedas declararlo como
final
en la interfaz, pero que no sea definitivo en la implementación. Hubiera tenido más sentido si cualquiera de los dos:a. No se permitió la palabra clave
final
para los argumentos del método de interfaz (abstracto) (pero puede usarlo en la implementación), o
segundo. declarar un argumento comofinal
en la interfaz lo forzaría a declararsefinal
en la implementación (pero no forzado para los no finales).
Puedo pensar en dos razones por las que una firma de método puede tener parámetros final
: Frijoles y Objetos ( En realidad, ambos son la misma razón, pero contextos ligeramente diferentes ) .
Objetos:
public static void main(String[] args) {
StringBuilder cookingPot = new StringBuilder("Water ");
addVegetables(cookingPot);
addChicken(cookingPot);
System.out.println(cookingPot.toString());
// ^--- OUTPUT IS: Water Carrot Broccoli Chicken ChickenBroth
// We forgot to add cauliflower. It went into the wrong pot.
}
private static void addVegetables(StringBuilder cookingPot) {
cookingPot.append("Carrot ");
cookingPot.append("Broccoli ");
cookingPot = new StringBuilder(cookingPot.toString());
// ^--- Assignment allowed...
cookingPot.append("Cauliflower ");
}
private static void addChicken(final StringBuilder cookingPot) {
cookingPot.append("Chicken ");
//cookingPot = new StringBuilder(cookingPot.toString());
// ^---- COMPILATION ERROR! It is final.
cookingPot.append("ChickenBroth ");
}
La palabra clave final
aseguró que no crearemos accidentalmente una nueva olla de cocina local al mostrar un error de compilación cuando intentamos hacerlo. Esto aseguró que el caldo de pollo se agregue a nuestra olla de cocina original que addChicken
método addChicken
. Compare esto con las addVegetables
en las que perdimos la coliflor porque la agregó a una olla de cocina local nueva en lugar de la olla original que obtuvo.
Frijoles: es el mismo concepto que los objetos (como se muestra arriba) . Los frijoles son esencialmente Object
en Java. Sin embargo, los beans (JavaBeans) se utilizan en diversas aplicaciones como una forma conveniente de almacenar y pasar una colección definida de datos relacionados. Del mismo modo que addVegetables
podría estropear el proceso de cocción al crear una nueva olla StringBuilder
y tirarla con la coliflor, también podría hacer lo mismo con una olla de cocina JavaBean .