简体   繁体   中英

NoSuchMethodException when using reflection

Interface...

package com.filter.tool
public interface Tool extends Resource {
...
    List findTools(int[] sizes, int counts);
}

Code...

package com.filter.tool.impl;
class Tool extends Resource implements com.filter.tool{ //default class (not visible)
Tool(Log log, Key key, Def def, Init init, Collection items) {
    super(log, key, def, init, null, null, 0, 0, 0, 0, 0, null, null, 0, false, items);
}
...
   public List findTools(int[] sizes, int counts) {
            ....
   }
...
}

In toolTest

package com.jtest.tool;
import com.filter.tool

public class ToolTest {

@Test
public void test(){
    int[] sizes = {1,2};
    int counts = 1;
    try { 
        Class<?> cls = Tool.class;
        Constructor<?> constructor = cls.getDeclaredConstructor();
        constructor.setAccessible(true);
        Tool tool = (Tool) constructor.newInstance();
        List pref = tool.findTools(sizes, counts);
        System.out.println(pref);
    } catch (Exception e) { 
        e.printStackTrace();
    }
}

When I run the test I got ..

java.lang.NoSuchMethodException: com.filter.tool.<init>()
    at java.lang.Class.getConstructor0(Class.java:2715)
    at java.lang.Class.getDeclaredConstructor(Class.java:1987)
    at com.att.lpp.prov.jtest.resman.impl.PoolTest.test(PoolTest.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    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:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

But if I change the package name from the toolTest it would warn me and tried to make me change the visibility of the code. I dont want to change the code. Am I missing something?

First: it seems, due to import in your test class, it tries to look for a constructor for an Interface instance, because com.filter.tool.Tool is the Tool interface, not a class. You have to rename your class or interface, to make it clearer or to do something with packages...

And the second: you have a constructor with arguments in your Tool class, that means, that you don't have a default one yet. But your test uses reflection to get a default constructor without arguments. You have to modify your test method logic, to make it looking for the constuctor with arguments, for that you have to call getDeclaredConstructor with arguments classes array like:

Class[] cArg = new Class[5];
cArg[0] = Log.class;
cArg[1] = Key.class;
...
Constructor<?> constructor = cls.getDeclaredConstructor(cArg);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM