【问题标题】:Why is my private constructor public when checked with reflection?为什么用反射检查我的私有构造函数是公共的?
【发布时间】:2017-11-22 18:01:04
【问题描述】:

我有(在许多其他没有这个问题的 Util 类中)一个 FileUtil 类,它没有通过私有构造函数的测试。

类定义为:

public final class FileUtil {

    /**
     * Hidden constructor to prevent instantiation.
     */
    private FileUtil() {
    }
    // ...
    // many static methods
}

如上所述,我还有许多其他类都经过测试,是否具有私有构造函数。测试方法是:

@Test
public void testPrivateConstructor() throws Exception {
    Constructor<FileUtil> constructor = FileUtil.class.getDeclaredConstructor();
    Assert.assertTrue("Constructor is not private", Modifier.isPrivate(constructor.getModifiers()));
    constructor.setAccessible(true);
    constructor.newInstance();
}

但是对于这个类 - 并且仅对于这个类 - isPrivate() 方法返回 false 并且如果在调试器中检查,则构造函数确实显示为 public。但是,如果尝试以编程方式调用构造函数,Eclipse 会告诉我该方法不可见。

我正在使用 Eclipse 和 Maven,当调用 Maven 构建时,问题显示在 Eclipse 和命令行中。所以这确实是一个 Java 问题,但是当我在整个库中毫无问题地使用这种模式时,我不明白为什么它只在这个类上失败。

有什么想法吗?

【问题讨论】:

  • 由于FileUtil 是一个常见的名称,也许您使用的是不同的FileUtil 类。在任何情况下,上面的代码都不应该给你false for isPrivate
  • 您是否创建了minimal reproducible example 来单独测试这个?我做到了,它工作得很好,所以@tsolakp 和@DwB 的建议几乎肯定是正确的......你正在寻找不同的FileUtil。对于这样的东西,总是在发布之前做一个minimal reproducible example。如果您自己没有发现问题,那么当您发布时,您就有了每个人都可以快速复制和验证的内容。
  • @JimGarrison 感谢您指出这一点。我在创建示例时找到了以下解决方案;-)

标签: java reflection private-constructor


【解决方案1】:

第一个猜测;这些不是您要查找的 FileUtil。

打印出FileUtil.class.getName()。 例如:

System.out.println("FileUtil classname: " + FileUtil.class.getName());

【讨论】:

    【解决方案2】:

    感谢您的回答。但是,问题是由完全不同的东西引起的:

    在其他一些测试中,我不得不模拟这个类的一些方法。由于所有方法都是静态的,我不得不使用

    @PrepareForTest(FileUtil.class)
    

    关于单元测试类。我想这就是我在 testPrivateConstructor() 方法中得到一个带有公共构造函数的模拟对象的原因。

    我将所有需要模拟的测试重构为一个单独的测试类,并从包含 testPrivateConstructor() 方法的测试类中删除了 @PrepareForTest(FileUtil.class)。现在它按预期工作了。

    希望如果有人再次遇到同样的问题,这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 1970-01-01
      • 2011-02-08
      • 2017-04-30
      • 2016-12-03
      • 1970-01-01
      • 2019-10-16
      相关资源
      最近更新 更多