À 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?
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.
Une classe anonyme n'est jamais
final
( §8.1.1.2 ).
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.
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.