web-dev-qa-db-fra.com

Résultat incorrect renvoyé par isAbstract () de la classe Modifier

À ma connaissance, le code suivant devrait imprimer False, mais lorsque j'ai exécuté ce code, il imprime True.

De Java docs:

Renvoie vrai si l'argument entier inclut le modificateur abstrait, faux sinon.

public class Test{
    public static void main(String[] args) {
        System.out.println(Modifier.isAbstract(byte[].class.getModifiers())); 
    }
}

Quelqu'un peut-il m'aider à comprendre ce comportement?

47
Joker

Javadoc de int Java.lang.Class.getModifiers () spécifie ce qui doit être retourné pour certains des modificateurs du tableau types (par exemple, le modificateur final doit être true et le modificateur interface doit être false). En revanche, il ne spécifie pas ce que les modificateurs abstract ou static doivent être pour les types de tableau, ce qui signifie la décision de retourner true ou false n'est pas documenté dans le JDK. Par conséquent, toute implémentation peut choisir de renvoyer true ou false.

int Java.lang.Class.getModifiers ()

Renvoie les modificateurs de langage Java pour cette classe ou interface, codés dans un entier. Les modificateurs sont constitués des constantes Java Virtual Machine pour public, protected, private, final, statique, abstrait et interface; ils doivent être décodés en utilisant les méthodes de la classe Modifier.

Si la classe sous-jacente est une classe de tableau, ses modificateurs public, privé et protégé sont les mêmes que ceux de son type de composant . Si cette classe représente un type primitif ou void, son modificateur public est toujours vrai, et ses modificateurs protégés et privés sont toujours faux. Si cet objet représente une classe de tableau , un type primitif ou void, alors son dernier modificateur est toujours vrai et son le modificateur d'interface est toujours faux . Les valeurs de ses autres modificateurs ne sont pas déterminées par cette spécification.

Les encodages des modificateurs sont définis dans The Java Virtual Machine Specification, tableau 4.1.

49
Eran

Une indication de ce comportement peut être trouvée dans le JLS, 10.8. Objets de classe pour les tableaux :

Chaque tableau a un objet Class associé, partagé avec tous les autres tableaux avec le même type de composant.

Bien qu'un type de tableau ne soit pas une classe, l'objet Class de chaque tableau agit comme si: [extrait]

Selon ce raisonnement, un tableau n'est pas une "vraie" classe, donc ce n'est certainement pas une classe concrète. La même logique s'appliquerait à int.class étant considéré comme abstrait.

6
Mureinik

La définition de abstract dit:

Une classe abstraite est une classe incomplète ou à considérer comme incomplète.

S'il y avait un tableau pur comme [] alors il serait en effet incomplet car aucun type de composant n'est fourni.

Cela violerait la spécification de 15.10.1. Expressions de création de tablea :

Il s'agit d'une erreur de compilation si ClassOrInterfaceType ne désigne pas un type réifiable.

Il ne désigne pas seulement un type réifiable, mais aucun type du tout. Ainsi, il serait impossible de créer des instances de [] - comme pour les classes abstraites.

Puisqu'il n'y a pas de tableau pur [] ce n'est qu'une sorte de spéculation. De plus, les modificateurs ont été renvoyés pour byte[]. Il reste la spécification indiquée par Eran .

3
LuCio

D'après ma compréhension, la spécification de langage Java pour getModifier () est:

Si la classe sous-jacente est une classe de tableau, ses modificateurs public, privé et protégé sont les mêmes que ceux de son type de composant. Si cette classe représente un type primitif ou vide, son modificateur public est toujours vrai, et ses modificateurs protégés et privés sont toujours faux

Maintenant, les valeurs de ses autres modificateurs ne sont pas déterminées par cette spécification, par ex. [~ # ~] résumé [~ # ~] .

D'après le tableau 4.1-A de JVMS:

ACC_ABSTRACT 0x0400 Résumé déclaré; ne doit pas être instancié.

2
Joker