我曾问过一个类似的问题,但我过早地接受了一个答案。又来了。
背景:我试图实例化一个类的构造函数,我通过它的坐标作为Maven依赖项导入。
问题:我遇到的问题是,这个类的特定构造函数,对我来说是不可见的,因为它没有关联的访问修饰符,所以它是默认的,这意味着我不能从外部访问它。
例子:我要使用的类在这里:
public class SomeClass {
// Notice no access modifier here so it's package-default
SomeClass(Log log, File in, File out) {
some stuff ...
}
// public constructor
public SomeClass() {}
// Method 1
public void compiler(File schema) {
some stuff ...
}
// Method 2
public void linker(File attribute) {
some stuff ...
}
}
这是我在一个单独项目中的顶层:
public class TopLevel {
public void testSomeClass() {
Constructor<SomeClass> constructor = SomeClass.class.getDeclaredConstructor(Log.class, File.class, File.class);
constructor.setAccessible(true);
// Default access level
SomeClass builder = constructor.newInstance(log, contentDirectory, outputDirectory);
//Here is where the problem occurs
builder.compiler(schemaFile);
}
}
备注:这似乎不起作用,上面的实现在我的顶层,构造函数和类中的方法现在对我来说都是可见的,我可以调用它们,但是我从ReflectiveCallable抽象方法中得到一个异常,当调用时,从反射方法抛出异常,而不是将其包装在InvocationTargetException中。似乎有一些错误的方式类DecisionTableBuilder被实例化。这就是我的问题。
我这样做对吗?是否有另一种方式来反映默认访问修改的构造函数/方法?当我显式地反映构造函数时,我是否也需要反映类的方法?
任何帮助都是非常感激的。提前感谢大家
编辑:这是我的堆栈跟踪,如果有人能理解这个…
java.lang.NullPointerException
at com.intuit.ctg.tla.compilers.SomeClass.compile(SomeClass.java:95)
at com.intuit.ctg.tla.compilers.qa.testSomeClass.testSomeClass(testCompilerLinker.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
我遵循这个堆栈跟踪到这行代码:
// This piece of code recursively searches in directory treesDirectory and
// lists all file with xml extentions
Collection<File> flowchartFiles = FileUtils.listFiles(treesDirectory, mapExtension, true);
不知怎的,treesDirectory(类型文件)得到一个NULL指针,即使我通过构造函数传递这个,这里作为第二个参数:
public static File treesDirectory = new File("src/test/resources/input_graphs/");
public static File outputDirectory = new File("src/test/resources/output");
public static Log log;
SomeClass builder = constructor.newInstance(log, treesDirectory, outputDirectory);
在反射构造函数中发生了一些有趣的事情…有人有什么想法吗?
默认构造函数
只能由同一包中的类访问。您可以在该包中创建自己的工厂(或构建器),并赋予其public
访问权限。也有可能API中已经提供了一个。
表示(部分)
如果没有指定访问修饰符
public
,protected
或private
,则在包含声明类成员的类的声明的整个包中都可以访问类成员或构造函数,但在任何其他包中都不能访问该类成员或构造函数。