【问题标题】:Differentiate provided default no args constructor from declared one将提供的默认无参数构造函数与声明的构造函数区分开来
【发布时间】:2019-01-20 01:45:07
【问题描述】:

简单问题:如何区分默认构造函数。即:

class AClass { } // will have a default no args constructor -> public AClass() {}

来自指定的类似:

class AClass {
    private final int i;

    public AClass() { i = 0; }
}

检查反射库提供的选项我无法找到任何可以让我区分它们的选项...

我主要使用Class#get*Constructor(s)提供的方法进行了尝试

也许我有狭隘的视野,我忘记了一些东西,或者我错过了另一种方法......任何帮助将不胜感激!

编辑:

这是我正在使用的方法,我需要检测这样的构造函数是否是用户定义的:

    protected void adaptAfterLoading(final Class<?> loadedClass) {
        Arrays.asList(loadedClass.getDeclaredConstructors()).forEach(System.out::println);
        System.out.println("$$$$$$$$$$$ " + loadedClass.getDeclaredConstructors());
        Arrays
                .stream(loadedClass.getDeclaredConstructors())
                .filter(
                        ((Predicate<Constructor<?>>) Constructor::isSynthetic)
                                .negate())
                .map(ConstructorRep::loadFrom)
                .forEach(this::addConstructor);
    }

所以...如果您想知道为什么 isSynthetic 不起作用:

来自here

13.1.二进制的形式 - 7. Java 编译器引入的任何在源代码中没有对应构造的构造都必须标记为合成,除了默认构造函数,类初始化方法,以及 Enum 类的 values 和 valueOf 方法。

【问题讨论】:

  • 你为什么真的想知道这个?
  • 你试过看Constructor class
  • 我真的怀疑有没有办法区分它。默认构造函数是在编译时添加的,因为反射是在运行时完成的,所以没有区别。
  • Why do you really want to know that?: 想象下一个要求,为给定的类编写一个方法,该方法将为此类定义创建骨架代码,构造函数具有各自的参数,因此对于方法,必须具有相同的声明字段依此类推...但是如果没有明确声明的方法/构造函数/字段,则不应将其写在骨架类代码定义中
  • 类中并不总是有构造函数——有一些非常奇怪的合成类最终没有构造函数。 See here.

标签: java reflection


【解决方案1】:

根本无法检测到这一点,因为编译后的字节码没有区别。

具有默认构造函数的类

class AClass { } // will have a default no args constructor 

被隐式编译为

class AClass { 
    AClass() {}
}

第一种形式只是语法糖。

还有你的下一个例子

class AClass {
    private final int i;

    public AClass() { i = 0; }
}

可以用等效形式的默认构造函数编写

class AClass {
    private final int i = 0;
}

此外,我没有看到您必须检测到这一点的用例。

【讨论】:

  • 阅读对我的问题的评论你为什么真的想知道这个?
猜你喜欢
  • 1970-01-01
  • 2014-07-05
  • 2012-07-19
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多