仅获取内部类构造函数的显式参数

问题描述 投票:0回答:1

constructor.getParameterTypes() 方法的文档是这样说的:

...请注意,某些内部类的构造函数除了显式声明的参数之外,还可能具有隐式声明的参数。

正如它所说,我尝试将它用于具有无参数构造函数的内部类,它给了我一个带有一个参数的构造函数(封闭类,下面的示例)。有没有简单的方法只获取显式参数?

import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;

public class TestInner{

    public class Inner{}

    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> innerClass = Class.forName("TestInner$Inner");
        Constructor<?>[] constructors = innerClass.getConstructors();
        String str = Arrays.stream(constructors).map(TestInner::stringifyConstructor).collect(Collectors.joining(", "));
        System.out.println(str);
    }
    public static String stringifyConstructor(Constructor c){
        return "("+Arrays.stream(c.getParameterTypes()).map(e->e.getName()).collect(Collectors.joining(", "))+")";
    }
}

我知道我可以删除第一个元素,但我怎么知道第一个元素是否是 100% 隐式的?似乎并非所有内部类都有这个参数(因为文档说“某些内部类可能”,而内部类如果我理解正确意味着非静态嵌套类)。是否有任何其他因素(除了非静态之外)可能导致该参数不存在?

java reflection
1个回答
0
投票

我如何知道第一个元素是否 100% 隐式?看来 并非所有内部类都有这个参数(因为文档说“一些 内部类可能”和内部类如果我理解正确的话意味着 非静态嵌套类)。是否还有其他因素(除了不 是静态的)会导致这个参数不存在?

无法通过编程方式判断,但 JLS 给出了规则:

非私有内部成员类的构造函数隐式声明一个代表该类的直接封闭实例的变量作为第一个形参。[.]

JLS 23,第 8.8.1 节

如果该类没有声明的构造函数,

默认构造函数没有形式参数,但在非私有内部成员类中除外,其中默认构造函数隐式声明一个表示该类的直接封闭实例的形式参数[.]

JLS 23,第 8.8.9 节

第 8.8.1 节中给出的基本原理有点技术性,但它归结为包含实例的类是否可能由与内部类本身不同的编译器编译。

尽管规范没有明确说明私有或非成员类的内部类的声明构造函数是否获得隐式额外参数,但此类类的默认构造函数明确不获得隐式额外参数这一事实似乎强烈暗示了这一点。 非成员内部类是本地类和匿名类。

另请注意,有一些嵌套类不是内部:那些显式声明的

static
、嵌套枚举和记录类以及接口的所有嵌套类。 此类的构造函数不会获得隐式额外参数,因为它们没有包含实例。

© www.soinside.com 2019 - 2024. All rights reserved.