150 votes

Méthode Java `final`: que promet-elle?

Dans une classe Java une méthode peut être définie de manière à être final, pour marquer que cette méthode ne peut pas être remplacée:

public class Thingy {
    public Thingy() { ... }
    public int operationA() {...}
    /** this method does @return That and is final. */
    public final int getThat() { ...}
}

C'est clair, et il peut être de quelque utilité pour protéger contre les chocs, écrasement, ou peut-être la performance — mais ce n'est pas ma question.

Ma question est: à Partir d'une OOP point de vue, j'ai compris que, par la définition d'une méthode final le concepteur de classes promet cette méthode fonctionnera toujours comme décrit, ou implicite. Mais souvent, cela peut être en dehors de l'influence de la classe auteur, si ce que la méthode est en train de faire est plus compliqué ensuite de livrer un bien.

La contrainte syntaxique est clair pour moi, mais quelle est l'implication dans le sens de la programmation orientée objet? Est - final utilisé correctement dans ce sens par la plupart des auteurs de classe?

Quel type de "contrat" est-ce un final méthode promesse?

161voto

NawaMan Points 10266

Pas exactement pourquoi vous avez demandé lorsque vous possédez déjà la plupart (si pas tous) de la réponse. Mais laissez-moi essayer, si je peut vous amener à comprendre.

Comme vous le mentionnez, final est utilisé avec une méthode en Java pour marquer que la méthode ne peut pas être remplacé (pour la portée de l'objet) ou caché (statique). Cela permet au développeur d'origine pour créer une fonctionnalité que l'on peut être sûr ne sera pas changé par d'autres, et c'est la garantie qu'il offre.

Cela signifie que si la méthode s'appuie sur d'autres composants personnalisables, comme la non-public des champs/méthodes de la fonctionnalité de la dernière méthode peut encore être personnalisable. C'est bon mais comme (avec le polymorphisme), il permet une personnalisation partielle.

Alors, pourquoi voulez-vous empêcher quelque chose d'être personnalisable, vous pouvez demander. Il existe un certain nombre de raisons.

  1. Pour permettre l'accès aux données encapsulées -- regarde immuable objet où ses attributs sont définis au moment de la construction et ne doit jamais être modifiée. Ou une valeur calculée dérivés de ces attributs. Un bon exemple est la Java de la classe String.

  2. De la fiabilité et de Contrat, les objets sont composées par des primitives de données ou d'autres moins-objets complexes. Pas toutes les opérations qui sont applicables à ces composants devraient être applicables ou même logique lorsqu'ils sont utilisés dans le plus grand objet. Méthode finale méthodes peuvent être utilisées pour s'assurer que. Compteur de classe est un bon exemple.


public class Counter {

    private int counter = 0;

    public final int count() {
        return counter++;
    }

    public final int reset() {
        return (counter = 0);
    }
}

Si le comte méthode n'est pas définitive, nous pouvons faire quelque chose comme ceci:

Counter c = new Counter() {   
    public int count() {
        super.count();   
        return super.count();   
    } 
}

c.count(); // now count 2

Ou quelque chose comme ceci:

Counter c = new Counter() {
  public int count() {
    int lastCount = 0;
    for (int i = super.count(); --i >= 0; ) {
      lastCount = super.count();
    }

    return lastCount;
  }
}

c.count(); // Now double count
  1. Performance -- Certains compilateurs peuvent analyser et d'optimiser l'opération, surtout sans effets secondaires.

C'est à partir du haut de ma tête.

Espérons que cela aide un peu.

29voto

josefx Points 8417

Quel type de "contrat" une méthode finale promet-elle?

En revanche, toute méthode non finale apporte la garantie implicite que vous pouvez la remplacer par votre propre implémentation et que la classe fonctionnera toujours comme prévu. Lorsque vous ne pouvez pas garantir que votre classe prend en charge l’écriture d’une méthode, vous devez la rendre définitive.

8voto

Victor Sorokin Points 7429

Tout d'abord, vous pouvez marquer les non-classes abstraites final ainsi que les champs et les méthodes. De cette façon, l'ensemble de la classe ne peut pas être sous-classé. Ainsi, le comportement de la classe sera fixé.

Je suis d'accord que les méthodes de marquage final ne garantit pas que leur comportement sera le même dans les sous-classes si ces méthodes font appel à la non-finale méthodes. Si le comportement est en effet besoin d'être fixe, ce doit être atteint par une convention et une conception soignée. Et n'oubliez pas de notion présente dans la javadoc!

Dernier point mais non le moins, final mot clé a un rôle très important dans Java Modèle de Mémoire (JMM). Il est garanti par JMM que pour obtenir une visibilité de final champs que vous n'avez pas besoin d'une synchronisation correcte. E. g.:

class A implements Runnable {
  final Sring caption = "Some caption";                           

  void run() {
    // no need to synchronize here to see proper value of final field
    System.out.println(caption);
  }
}  

0voto

Brian Roach Points 43787

Non, ce n'est pas en dehors de l'influence de l'auteur de la classe. Vous ne pouvez pas le remplacer dans votre classe dérivée, donc il fera ce que l'auteur de la classe de base avait prévu.

http://download.oracle.com/javase/tutorial/java/IandI/final.html

Il convient de noter la partie où elle suggère que les méthodes appelées à partir de constructeurs devraient être final .

0voto

Jim Ferrans Points 13673

Je ne suis pas sûr que vous puissiez affirmer l'utilisation de "final" et son incidence sur le contrat de conception global du logiciel. Vous êtes assuré qu'aucun développeur ne peut ignorer cette méthode et annuler son contrat de cette façon. Mais d'autre part, la dernière méthode peut se fonder sur des variables de classe ou d' instance dont les valeurs sont fixées par les sous - classes, et peut appeler d' autres méthodes de classe qui sont surchargées. Donc finale est tout au plus une garantie très faible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X