文档

Java™ 教程-Java Tutorials 中文版
获取方法参数的名称
Trail: The Reflection API
Lesson: Members
Section: Methods

获取方法参数的名称

你可以使用方法 java.lang.reflect.Executable.getParameters 获取任何方法或构造函数的形式参数的名称。(类 MethodConstructor 继承类 Executable 因此继承方法 Executable.getParameters。)但是,.class 文件默认不存储形式参数名。这是因为许多生成和使用类文件的工具可能不会期望包含参数名称的 .class 文件的较大静态和动态占用空间。特别是,这些工具必须处理较大的 .class 文件,Java 虚拟机(JVM)将使用更多内存。此外,某些参数名称(如 secretpassword)可能会公开有关安全性敏感方法的信息。

要将形式参数名称存储在特定的 .class 文件中,从而使反射 API 能够获取形式参数名称,请带 -parameters 选项使用 javac 编译器编译源文件 。

MethodParameterSpy 示例说明了如何获取给定类的所有构造函数和方法的形式参数的名称。该示例还打印有关每个参数的其他信息。

以下命令打印类 ExampleMethods 的构造函数和方法的形式参数名称。注意:请记住使用 -parameters 编译器选项编译示例 ExampleMethods

java MethodParameterSpy ExampleMethods

此命令打印以下内容:

Number of constructors: 1

Constructor #1
public ExampleMethods()

Number of declared constructors: 1

Declared constructor #1
public ExampleMethods()

Number of methods: 4

Method #1
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
             Return type: boolean
     Generic return type: boolean
         Parameter class: class java.lang.String
          Parameter name: stringParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false
         Parameter class: int
          Parameter name: intParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #2
public int ExampleMethods.varArgsMethod(java.lang.String...)
             Return type: int
     Generic return type: int
         Parameter class: class [Ljava.lang.String;
          Parameter name: manyStrings
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #3
public boolean ExampleMethods.methodWithList(java.util.List<java.lang.String>)
             Return type: boolean
     Generic return type: boolean
         Parameter class: interface java.util.List
          Parameter name: listParam
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

Method #4
public <T> void ExampleMethods.genericMethod(T[],java.util.Collection<T>)
             Return type: void
     Generic return type: void
         Parameter class: class [Ljava.lang.Object;
          Parameter name: a
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false
         Parameter class: interface java.util.Collection
          Parameter name: c
               Modifiers: 0
            Is implicit?: false
        Is name present?: true
           Is synthetic?: false

MethodParameterSpy 示例使用 Parameter 类中的以下方法:

隐式和合成参数

如果没有显式地编写某些构造函数,则在源代码中隐式声明它们。例如,ExampleMethods 示例不包含构造函数。默认构造函数是为它隐式声明的。MethodParameterSpy 示例打印有关 ExampleMethods 的隐式声明构造函数的信息:

Number of declared constructors: 1
public ExampleMethods()

请考虑以下 MethodParameterExamples 的片段:

public class MethodParameterExamples {
    public class InnerClass { }
}

InnerClass 是非静态 嵌套类 或内部类。内部类的构造函数也是隐式声明的。但是,此构造函数将包含一个参数。当 Java 编译器编译 InnerClass 时,它会创建一个 .class 文件,该文件代表类似于以下内容的代码:

public class MethodParameterExamples {
    public class InnerClass {
        final MethodParameterExamples parent;
        InnerClass(final MethodParameterExamples this$0) {
            parent = this$0; 
        }
    }
}

InnerClass 构造函数包含一个参数,其类型是包含 InnerClass 的类,即 MethodParameterExamples。因此,示例 MethodParameterExamples 将打印以下内容:

public MethodParameterExamples$InnerClass(MethodParameterExamples)
         Parameter class: class MethodParameterExamples
          Parameter name: this$0
               Modifiers: 32784
            Is implicit?: true
        Is name present?: true
           Is synthetic?: false

因为隐式声明了类 InnerClass 的构造函数,所以它的参数也是隐式的。

注意:

如果 Java 编译器产生的构造函数与源代码中显式或隐式声明的构造函数不对应,则将其标记为 synthetic,除非它们是类初始化方法。合成构造函数是由编译器生成的工件,这些工件在不同的实现之间变化。请考虑以下 MethodParameterExamples 的片段:

public class MethodParameterExamples {
    enum Colors {
        RED, WHITE;
    }
}

当 Java 编译器遇到 enum 构造时,它会创建几个与 .class 文件结构兼容的方法,并提供预期功能的 enum 构造。例如,Java 编译器将为 enum 构造 Colors 创建一个 .class 文件,该文件代表类似于以下内容的代码:

final class Colors extends java.lang.Enum<Colors> {
    public final static Colors RED = new Colors("RED", 0);
    public final static Colors BLUE = new Colors("WHITE", 1);
 
    private final static values = new Colors[]{ RED, BLUE };
 
    private Colors(String name, int ordinal) {
        super(name, ordinal);
    }
 
    public static Colors[] values(){
        return values;
    }
 
    public static Colors valueOf(String name){
        return (Colors)java.lang.Enum.valueOf(Colors.class, name);
    }
}

Java 编译器为此 enum 构造创建三个构造函及方法:Colors(String name, int ordinal)Colors[] values(),和 Colors valueOf(String name)。方法 valuesvalueOf 是隐式声明的。因此,它们的形式参数名也被隐式声明。

enum 构造函数 Colors(String name, int ordinal) 是默认构造函数,它是隐式声明的。但是,此构造函数的形式参数(nameordinal) 不是 隐式声明的。因为这些形式参数既不是显式声明,也不是隐式声明,所以它们是合成的。(enum 构造的默认构造函数的形式参数未被隐式声明,因为不同的编译器不需要在此构造函数的形式上达成一致;另一个 Java 编译器可能为其指定不同的形式参数。当编译器编译使用 enum 常量的表达式时,它们只依赖于隐式声明的 enum 构造的公共静态字段,而不是它们的构造函数或这些常量如何被初始化。)

因此,示例 MethodParameterExample 打印有关 enum 构造 Colors 的以下内容:

enum Colors:

Number of constructors: 0

Number of declared constructors: 1

Declared constructor #1
private MethodParameterExamples$Colors()
         Parameter class: class java.lang.String
          Parameter name: $enum$name
               Modifiers: 4096
            Is implicit?: false
        Is name present?: true
           Is synthetic?: true
         Parameter class: int
          Parameter name: $enum$ordinal
               Modifiers: 4096
            Is implicit?: false
        Is name present?: true
           Is synthetic?: true

Number of methods: 2

Method #1
public static MethodParameterExamples$Colors[]
    MethodParameterExamples$Colors.values()
             Return type: class [LMethodParameterExamples$Colors;
     Generic return type: class [LMethodParameterExamples$Colors;

Method #2
public static MethodParameterExamples$Colors
    MethodParameterExamples$Colors.valueOf(java.lang.String)
             Return type: class MethodParameterExamples$Colors
     Generic return type: class MethodParameterExamples$Colors
         Parameter class: class java.lang.String
          Parameter name: name
               Modifiers: 32768
            Is implicit?: true
        Is name present?: true
           Is synthetic?: false

有关隐式声明的构造的更多信息,请参阅 Java Language Specification,包括在反射 API 中显示为隐式的参数。


Previous page: Obtaining Method Type Information
Next page: Retrieving and Parsing Method Modifiers