检索和解析构造器修饰符

原文: https://docs.oracle.com/javase/tutorial/reflect/member/ctorModifiers.html

由于构造器在语言中的作用,修饰符比方法更有意义:

  • 访问修饰符:publicprotectedprivate
  • 注释

ConstructorAccess 示例使用指定的访问修饰符搜索给定类中的构造器。它还显示构造器是合成的(编译器生成的)还是可变的 arity。

  1. import java.lang.reflect.Constructor;
  2. import java.lang.reflect.Modifier;
  3. import java.lang.reflect.Type;
  4. import static java.lang.System.out;
  5. public class ConstructorAccess {
  6. public static void main(String... args) {
  7. try {
  8. Class<?> c = Class.forName(args[0]);
  9. Constructor[] allConstructors = c.getDeclaredConstructors();
  10. for (Constructor ctor : allConstructors) {
  11. int searchMod = modifierFromString(args[1]);
  12. int mods = accessModifiers(ctor.getModifiers());
  13. if (searchMod == mods) {
  14. out.format("%s%n", ctor.toGenericString());
  15. out.format(" [ synthetic=%-5b var_args=%-5b ]%n",
  16. ctor.isSynthetic(), ctor.isVarArgs());
  17. }
  18. }
  19. // production code should handle this exception more gracefully
  20. } catch (ClassNotFoundException x) {
  21. x.printStackTrace();
  22. }
  23. }
  24. private static int accessModifiers(int m) {
  25. return m & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
  26. }
  27. private static int modifierFromString(String s) {
  28. if ("public".equals(s)) return Modifier.PUBLIC;
  29. else if ("protected".equals(s)) return Modifier.PROTECTED;
  30. else if ("private".equals(s)) return Modifier.PRIVATE;
  31. else if ("package-private".equals(s)) return 0;
  32. else return -1;
  33. }
  34. }

没有明确的 Modifier 常量对应于“包私有”访问,因此有必要检查是否缺少所有三个访问修饰符以识别包私有构造器。

此输出显示 java.io.File 中的私有构造器:

  1. $ java ConstructorAccess java.io.File private
  2. private java.io.File(java.lang.String,int)
  3. [ synthetic=false var_args=false ]
  4. private java.io.File(java.lang.String,java.io.File)
  5. [ synthetic=false var_args=false ]

合成构造器很少见;然而, SyntheticConstructor示例说明了可能发生这种情况的典型情况:

  1. public class SyntheticConstructor {
  2. private SyntheticConstructor() {}
  3. class Inner {
  4. // Compiler will generate a synthetic constructor since
  5. // SyntheticConstructor() is private.
  6. Inner() { new SyntheticConstructor(); }
  7. }
  8. }
  1. $ java ConstructorAccess SyntheticConstructor package-private
  2. SyntheticConstructor(SyntheticConstructor$1)
  3. [ synthetic=true var_args=false ]

由于内部类的构造器引用了封闭类的私有构造器,因此编译器必须生成包私有构造器。参数类型SyntheticConstructor$1是任意的,取决于编译器实现。取决于是否存在任何合成或非公共类成员的代码可能无法移植。

构造器实现 java.lang.reflect.AnnotatedElement ,它提供了使用 java.lang.annotation.RetentionPolicy.RUNTIME 检索运行时注释的方法。有关获取注释的示例,请参阅检查类修饰符和类型部分。