web-dev-qa-db-fra.com

Classes Anonymous-Inner montrant un modificateur incorrect

À ma connaissance, le code suivant aurait dû imprimer true en sortie.

Cependant, lorsque j'ai exécuté ce code, il imprime false.

De Java docs of Anonymous Classes 15.9.5. :

Une classe anonyme est toujours implicitement définitive

public class Test {
    public static void main(String args[]) {
        Object o = new Object() {
        };
        System.out.println("Annonymous class is final: " + Modifier.isFinal(o.getClass().getModifiers()));
    }
}

Pourquoi ce code se comporte comme ça?

45
Joker

Notez que le libellé dans le JLS de cette section particulière a considérablement changé depuis lors. Il contient maintenant (JLS 11):

15.9.5. Déclarations de classe anonymes :

Une classe anonyme n'est jamais définitive ( §8.1.1.2 ).

Le fait qu'une classe anonyme ne soit pas finale est pertinent pour le casting, en particulier la conversion de référence de rétrécissement autorisée pour l'opérateur de cast ( §5.5 ). Elle présente également un intérêt pour la sous-classe, car il est impossible de déclarer une sous-classe d'une classe anonyme, bien qu'une classe anonyme ne soit pas finale, car une classe anonyme ne peut pas être nommée par une clause extend ( §8.1. 4 ).

Ce changement de formulation a été introduit dans JLS 9. La sémantique des classes anonymes et le comportement des méthodes dans la question sont restés inchangés, l'intention était d'éviter exactement le genre de confusion sur laquelle porte cette question.

Le ticket qui a provoqué le changement dit:

Le comportement de longue date de javac, depuis 1.3, a été, pour la plupart, pas de traiter les classes comme "finales". Pour remédier à cette incohérence, la spécification doit être modifiée pour refléter avec précision l'implémentation de référence.

Plus précisément, les classes anonymes ne sont presque jamais générées avec le jeu d'indicateurs ACC_FINAL. Nous ne pouvons pas modifier ce comportement de longue date sans avoir un impact sur certains clients de sérialisation (cela serait autorisé, mais perturbe inutilement). Et nous ne pouvons pas fidèlement implémenter Class.getModifers (qui promet de fournir les "modificateurs de langage Java") sans les fichiers de classe encodant les modificateurs du langage.

47
Hulk

Une classe anonyme n'est jamais final ( §8.1.1.2 ).

JLS 11 - 15.9.5. Déclarations de classe anonymes

Je ne connaissais pas le raisonnement derrière cela, mais, selon la réponse de @ Hulk et ce rapport de bogue , il semble que les spécifications des versions précédentes nous aient légèrement induits en erreur en disant que les classes anonymes sont finales.

10
Andrew Tobilko

Les classes anonymes sont considérées implicitement final car vous ne pouvez pas en créer de sous-classes. Cela ne signifie pas que le Modifier.FINAL le modificateur doit être défini pour les classes anonymes.

9
Eran