Modificateur de constructeur «transitoire» inattendu

J’ai trouvé une chose intéressante en travaillant avec la reflection. J’ai essayé de récupérer des constructeurs de classe simple et leurs modificateurs.

public class Test { public Test(Object... args) {} } 

Voici le code pour récupérer les modificateurs de constructeur:

 Class clazz = Test.class; Constructor[] ctors = clazz.getDeclaredConstructors(); for (Constructor ctor : ctors) { int mod = ctor.getModifiers(); /*if not package-private modifier*/ if(mod!=0) { System.out.println( Modifier.toSsortingng(mod))); } } 

Le résultat est:

  public transient 

Si je passe au constructeur pas des parameters variables, mais juste un tableau, ça va.

 public class Test { public Test(Object[] args) {} } 

Le résultat est:

  public 

La même chose se produit quels que soient le modificateur de constructeur (public, protégé, privé) ou le type de paramètre (primitif ou référence). Comment pourrait-il en être ainsi, alors que “transitoire” n’est pas un modificateur valide pour le constructeur?

Les modificateurs d’access sont codés sous forme de masques binarys dans le fichier de classe. La spécification JVM atsortingbue une signification différente à certains des bits selon qu’ils apparaissent dans un modificateur de méthode ou un modificateur de champ. Le bit 7 ( 0x0080 ) en est un.

Pour les méthodes :

 ACC_VARARGS 0x0080 Declared with variable number of arguments. 

Pour les champs :

 ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent object manager. 

Puisque vous utilisez une méthode, l’interprétation correcte de ce modificateur est ACC_VARARGS et non ACC_TRANSIENT .

Cependant, la classe de Modifier semble uniquement capable de traiter un sous-ensemble de modificateurs définis dans les spécifications de la machine virtuelle Java. Comme tout ce qu’il faut, c’est un int , il est impossible de distinguer ACC_VARARGS et ACC_TRANSIENT .