En Java, il est parfaitement légal de définir des final
arguments dans les méthodes d'interface et de ne pas obéir à cela dans la classe d'implémentation, par exemple:
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) {
...
}
}
Dans l'exemple ci-dessus, bar
et baz
a les final
définitions opposées dans la classe VS l'interface.
De la même manière, aucune final
restriction n'est appliquée lorsqu'une méthode de classe en étend une autre, que ce soit abstract
ou non.
Bien que final
le corps de la méthode de classe ait une valeur pratique, y a-t-il un point précisant les final
paramètres de la méthode d'interface?
final
ne fait rien avec les types natifs de toute façon, puisqu'ils sont copiés.interface
définitions ne varient que dans l'final
attribut d'un argument, alors les.class
fichiers résultants sont octet pour octet de manière identique (etjavap -v
produisent bien sûr la même sortie). La même chose est vraie pour deux classes qui ne diffèrent quefinal
sur un attribut, d'ailleurs!Réponses:
Il ne semble pas y avoir de raison. Selon la spécification du langage Java 4.12.4 :
Cependant, un
final
modificateur sur un paramètre de méthode n'est pas mentionné dans les règles de correspondance des signatures de méthodes remplacées, et il n'a aucun effet sur l'appelant, uniquement dans le corps d'une implémentation. De plus, comme l'a noté Robin dans un commentaire, lefinal
modificateur sur un paramètre de méthode n'a aucun effet sur le code d'octet généré. (Ce n'est pas vrai pour les autres utilisations definal
.)la source
final
modificateur n'est pas appliqué à la classe d'implémentation. Votre signature d'interface peut simplement mentir.Certains IDE copient la signature de la méthode abstraite / d'interface lors de l'insertion d'une méthode d'implémentation dans une sous-classe.
Je ne pense pas que cela fasse une différence pour le compilateur.
EDIT: Bien que je pense que c'était vrai dans le passé, je ne pense pas que les IDE actuels le fassent plus.
la source
static transient
domaines. ;)Les annotations finales des paramètres de méthode sont toujours pertinentes uniquement pour l'implémentation de la méthode, jamais pour l'appelant. Par conséquent, il n'y a aucune vraie raison de les utiliser dans les signatures de méthode d'interface. Sauf si vous souhaitez suivre la même norme de codage cohérente, qui nécessite des paramètres de méthode finaux, dans toutes les signatures de méthode. Alors c'est bien de pouvoir le faire.
la source
Mise à jour: La réponse originale ci-dessous a été rédigée sans bien comprendre la question, et ne répond donc pas directement à la question.
:)
Néanmoins, elle doit être informative pour ceux qui cherchent à comprendre l'utilisation générale dufinal
mot - clé.Pour ce qui est de la question, je voudrais citer mon propre commentaire ci-dessous.
Je peux penser à deux raisons pour lesquelles une signature de méthode peut avoir des
final
paramètres: Beans et Objects (en fait, ce sont tous les deux la même raison, mais des contextes légèrement différents. )Objets:
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 "); }
Le
final
mot-clé garantit que nous ne créerons pas accidentellement une nouvelle marmite locale en affichant une erreur de compilation lorsque nous avons tenté de le faire. Cela garantit que le bouillon de poulet est ajouté à notre marmite d'origine que laaddChicken
méthode a obtenue. Comparez cela à l'addVegetables
endroit où nous avons perdu le chou-fleur parce qu'il l'a ajouté à une nouvelle marmite locale au lieu de la marmite d'origine.Beans: C'est le même concept que les objets (comme indiqué ci-dessus) . Les beans sont essentiellement des
Object
s en Java. Cependant, les beans (JavaBeans) sont utilisés dans diverses applications comme un moyen pratique de stocker et de transmettre une collection définie de données associées. Tout comme leaddVegetables
pourrait gâcher le processus de cuisson en créant une nouvelle marmiteStringBuilder
et en le jetant avec le chou-fleur, il pourrait également faire de même avec une marmite JavaBean .la source
final
dans l'interface, mais que ce soit non final dans l'implémentation. Cela aurait été plus logique si (a)final
mot-clé n'était pas autorisé pour les arguments de la méthode d'interface (abstraite) (mais vous pouvez l'utiliser dans l'implémentation), ou (b) déclarer un argument commefinal
dans interface le forcerait à être déclaréfinal
dans l'implémentation (mais pas forcé pour les non-finales).:)
Je pense que c'est peut-être un détail superflu, car le fait qu'il soit définitif ou non est un détail de mise en œuvre.
(Un peu comme déclarer des méthodes / membres dans une interface comme public.)
la source