文档

Java™ 教程-Java Tutorials 中文版
获取和解析构造函数修饰符
Trail: The Reflection API
Lesson: Members
Section: Constructors

获取和解析构造函数修饰符

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

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


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 常量对应于“package-private”访问,因此有必要检查是否缺少所有三个访问修饰符来识别包包私有构造函数。

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

$ 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 示例说明了可能发生这种情况的典型情况:


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

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

构造函数实现 java.lang.reflect.AnnotatedElement,它提供了获取使用 java.lang.annotation.RetentionPolicy.RUNTIME 的运行时注解。有关获取注解的示例,请参阅 Examining Class Modifiers and Types 部分。


Previous page: Finding Constructors
Next page: Creating New Class Instances