# 检索和解析构造器修饰符

> 原文： [https://docs.oracle.com/javase/tutorial/reflect/member/ctorModifiers.html](https://docs.oracle.com/javase/tutorial/reflect/member/ctorModifiers.html)

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

*   访问修饰符：`public`，`protected`和`private`
*   注释

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

```java
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import static java.lang.System.out;

public class ConstructorAccess {
    public static void main(String... args) {
	try {
	    Class<?> c = Class.forName(args[0]);
	    Constructor[] allConstructors = c.getDeclaredConstructors();
	    for (Constructor ctor : allConstructors) {
		int searchMod = modifierFromString(args[1]);
		int mods = accessModifiers(ctor.getModifiers());
		if (searchMod == mods) {
		    out.format("%s%n", ctor.toGenericString());
		    out.format("  [ synthetic=%-5b var_args=%-5b ]%n",
			       ctor.isSynthetic(), ctor.isVarArgs());
		}
	    }

        // production code should handle this exception more gracefully
	} catch (ClassNotFoundException x) {
	    x.printStackTrace();
	}
    }

    private static int accessModifiers(int m) {
	return m & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
    }

    private static int modifierFromString(String s) {
	if ("public".equals(s))               return Modifier.PUBLIC;
	else if ("protected".equals(s))       return Modifier.PROTECTED;
	else if ("private".equals(s))         return Modifier.PRIVATE;
	else if ("package-private".equals(s)) return 0;
	else return -1;
    }
}

```

没有明确的 [`Modifier`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html) 常量对应于“包私有”访问，因此有必要检查是否缺少所有三个访问修饰符以识别包私有构造器。

此输出显示 [`java.io.File`](https://docs.oracle.com/javase/8/docs/api/java/io/File.html) 中的私有构造器：

```java
$ java ConstructorAccess java.io.File private
private java.io.File(java.lang.String,int)
  [ synthetic=false var_args=false ]
private java.io.File(java.lang.String,java.io.File)
  [ synthetic=false var_args=false ]

```

合成构造器很少见;然而， [``SyntheticConstructor``](example/SyntheticConstructor.java)示例说明了可能发生这种情况的典型情况：

```java
public class SyntheticConstructor {
    private SyntheticConstructor() {}
    class Inner {
	// Compiler will generate a synthetic constructor since
	// SyntheticConstructor() is private.
	Inner() { new SyntheticConstructor(); }
    }
}

```

```java
$ java ConstructorAccess SyntheticConstructor package-private
SyntheticConstructor(SyntheticConstructor$1)
  [ synthetic=true  var_args=false ]

```

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

构造器实现 [`java.lang.reflect.AnnotatedElement`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html) ，它提供了使用 [`java.lang.annotation.RetentionPolicy.RUNTIME`](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/RetentionPolicy.html#RUNTIME) 检索运行时注释的方法。有关获取注释的示例，请参阅[检查类修饰符和类型](../class/classModifiers.html)部分。