The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
Because of the role of constructors in the language, fewer modifiers are meaningful than for methods:
public
, protected
, and private
The
example searches for constructors in a given class with the specified access modifier. It also displays whether the constructor is synthetic (compiler-generated) or of variable arity.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; } }
There is not an explicit Modifier
constant which corresponds to "package-private" access, so it is necessary to check for the absence of all three access modifiers to identify a package-private constructor.
This output shows the private constructors in 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 ]
Synthetic constructors are rare; however the
example illustrates a typical situation where this may occur: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 ]
Since the inner class's constructor references the private constructor of the enclosing class, the compiler must generate a package-private constructor. The parameter type SyntheticConstructor$1
is arbitrary and dependent on the compiler implementation. Code which depends on the presence of any synthetic or non-public class members may not be portable.
Constructors implement java.lang.reflect.AnnotatedElement
, which provides methods to retrieve runtime annotations with java.lang.annotation.RetentionPolicy.RUNTIME
. For an example of obtaining annotations see the Examining Class Modifiers and Types section.