如何访问具有默认访问权限的构造函数(或package-default)

时间:2015-07-16 22:07:24

标签: java maven reflection access-modifiers

我正在尝试实例化一个类的构造函数,我通过它的坐标将其作为Maven依赖项导入。我遇到的问题是这个类的特定构造函数对我来说是不可见的,因为它没有与之关联的访问修饰符,因此它是默认的,这意味着我无法从外部访问它。

我知道有一种方法可以通过反射访问私有方法,使用类Method的getDeclaredMethod()方法,但是这对构造函数不起作用(如果我错了,请纠正我)。

我正在尝试使用的课程在这里:

public class DecisionTableBuilder {

   // Notice no access modifier here so it's package-default
   DecisionTableBuilder(Log log, File in, File out) {
      some stuff ...
   }

   // public constructor
   public DecisionTableBuilder() {}

   // Method 1
   public void compiler(File schema) {
      some stuff ...
   }

   // Method 2
   public void linker(File attribute) {
      some stuff ...
   }
}

这是我在一个单独的项目中的顶层:

public class TopLevel {

   public void testDecisionTableBuilder() {

      // I get an error saying the constructor DecisionTableBuilder is not visible
      DecisionTableBuilder builder = new DecisionTableBuilder();

      // This works just fine, but no constructor...
      DecisionTableBuilder builder2;

      // This doesn't really work
      Method[] m = DecisionTableBuilder.class.getDeclaredMethods("DecisionTableBuilder", "Log", "File", "File");

   }
}

如何访问我在新项目中创建的顶级类中的构造函数和方法?任何帮助将不胜感激

修改

public File graphDir;
public File outputDir;
public Log log;

Constructor<DecisionTableBuilder> constructor = DecisionTableBuilder.class.getDeclaredConstructor(Log.class,File.class,File.class);
constructor.setAccessible(true);
DecisionTableBuilder builder =constructor.newInstance(log, graphDir, outputDir);

这是正确的吗?

1 个答案:

答案 0 :(得分:2)

您无法使用getDeclaredMethodgetDeclaredMethods访问构造函数。 Java反射机制区分方法和构造函数,并且具有访问它们的单独方法。

尝试getDeclaredConstructors method

Constructor[] c = DecisionTableBuilder.class.getDeclaredConstructors();

或针对特定构造函数getDeclaredConstructor。传入表示参数类型的Class对象,而不是类的字符串名称。

Constructor<DecisionTableBuilder> constructor =
    DecisionTableBuilder.class.getDeclaredConstructor(Log.class, File.class, File.class);

您需要将其设置为可访问,然后致电newInstance以创建DecisionTableBuilder

constructor.setAccessible(true);
DecisionTableBuilder dtb = constructor.newInstance(yourLog, inFile, outFile);

您当然需要catch这些反射调用可以抛出的几个异常。