我问了一个类似的问题,但我过早地接受了答案。这是再次。
上下文 我正在尝试实例化一个类的构造函数,我通过它的坐标将其作为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(类型File)获取一个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);
在反映的构造函数中发生了一些有趣的事情......有人有什么想法吗?我已经在这2天了...
答案 0 :(得分:1)
只能由同一个包中的类访问。您可以在该包中创建自己的工厂(或构建器)并为其提供public
访问权限。您的API中也可能已经提供了一个。
说(部分)
如果未指定任何访问修饰符
public
,protected
或private
,则可以在整个包中访问类成员或构造函数,其中包含类的声明,其中声明了类成员,但是在任何其他包中都无法访问类成员或构造函数。