Méthodes Non finales dans une classe finale

Ma question est assez simple:
Le compilateur traite-t-il Toutes les méthodes d'une classe finale comme étant finales elles-mêmes? L'ajout du mot-clé final aux méthodes d'une classe finale a-t-il un effet?

J'ai compris que les méthodes finales ont une meilleure chance de s'intégrer et c'est pourquoi je demande.

Merci d'avance.

26
demandé sur Acidic 2012-01-07 05:08:13

3 réponses

Vous avez raison, toutes les méthodes d'une classe finale sont implicitement finales.

Voir ici:

"notez que vous pouvez également déclarer une finale de classe entière. Une classe qui est déclaré final ne peut pas être sous-classé. Ceci est particulièrement utile, pour exemple, lors de la création d'une classe immuable comme la classe String."

Et ici:

Toutes les méthodes d'une classe finale sont implicitement finales.

Cela peut également vous intéresser: conseils de Performance pour le mot clé Java final

27
répondu EboMike 2012-01-07 01:10:02

Le compilateur traite-t-il Toutes les méthodes d'une classe finale comme étant finales elles-mêmes?

En effet, Oui. Une méthode dans une classe final ne peut pas être remplacée. L'ajout (ou la suppression) d'un mot clé final à une méthode ne fait aucune différence avec cette règle.

L'ajout du mot-clé final aux méthodes d'une classe finale a-t-il un effet?

En pratique, il a un effet minimal. Cela n'a aucun effet sur les règles de substitution (voir ci-dessus), et non effet sur inline (voir ci-dessous).

Il est possible de dire à l'exécution si une méthode a été déclarée avec un mot clé final... utilisation de la réflexion pour regarder les drapeaux de la méthode. Donc, il a un effet , bien qu'un effet qui n'est pas pertinent pour 99,99% des programmes.

J'ai compris que les méthodes finales ont de meilleures chances d'être intégrées et c'est pourquoi je demande.

Cette compréhension est incorrecte . Le compilateur JIT dans un JVM garde une trace des méthodes qui ne sont pas remplacées dans les classes chargées par une application. Il utilise ces informations et les types statiques pour déterminer si un appel particulier nécessite une répartition de classe virtuelle ou non. Si ce n'est pas le cas, l'inlining est possible et sera utilisé en fonction de la taille du corps de la méthode. En effet, le compilateur JIT ignore la présence / absence de final et utilise une méthode plus précise pour détecter les appels de méthode où l'inlining de la méthode est admissibles.

(En fait c'est plus complexe que cela. Une application peut charger dynamiquement des sous-classes qui font que l'analyse de substitution de méthode du compilateur JIT devient incorrecte. Si cela se produit, la JVM doit invalider toutes les méthodes compilées effectuées et les faire recompiler.)


La ligne du bas est:

  • Il N'y a pas d'avantage de performance à ajouter final aux méthodes dans les classes final.

  • Il peut un avantage de performance dans final aux méthodes dans les classes non-final, mais seulement si vous utilisez une ancienne JVM Sun, ou une autre plate-forme Java / Java avec un compilateur JIT de mauvaise qualité.

Si vous vous souciez des performances, il est préférable d'utiliser une plate-forme Java à jour / haute performance avec un compilateur JIT décent que de polluer votre base de code avec des mots-clés final susceptibles de vous causer des problèmes à l'avenir.


Vous avez écrit dans un commentaire:

@ RussellZahniser j'ai lu différemment dans de nombreux endroits.

Internet regorge d'informations anciennes, dont une grande partie est obsolète ... ou n'a jamais été correct en premier lieu.

7
répondu Stephen C 2012-01-07 02:51:17

Peut être que le compilateur les traite comme final.

Ce qui suit imprime "false":

final class FinalClass {
    public void testMethod() {}
}

Method method = FinalClass.class.getDeclaredMethod("testMethod");
int m = method.getModifiers();
System.out.println(Modifier.isFinal(m));
5
répondu Bhesh Gurung 2012-01-07 01:16:52