对于我的程序,目标是使用一堆接口并创建一个进行测试并允许用户进行测试的程序。我遇到的具体问题是接口IQuestionFactory,它可以帮助在TestMaker类中提出问题。我正在使用教授提供的类加载器,该类加载器使用我需要加载的类的名称作为参数。我无法弄清楚为什么会出错。

错误

java.lang.NoSuchMethodException: test.api.IQuestionFactory.<init>()
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getConstructor(Unknown Source)
    at test.util.MyClassLoader.createInstance(MyClassLoader.java:37)
    at test.maker.TestMaker.main(TestMaker.java:13)
Exception in thread "main" java.lang.NullPointerException
    at test.maker.TestMaker.main(TestMaker.java:14)


类加载器

package test.util;

import java.lang.reflect.Constructor;

public class MyClassLoader {

    //instead of using the constructor, we provide a single instance of MyClassLoader
    public static MyClassLoader instance = new MyClassLoader();

    //by making the constructor private, we ensure that it can't be called.
    private MyClassLoader() {

    }

    /**
     * Load class of the given className and create an object of that class.
     * @param className the name of the class including its package. e.g.  test.impl.QuestionFactory
     * @return return the object created.
     */
    public Object createInstance(String className) {
        try {
            ClassLoader classLoader = this.getClass().getClassLoader();
            Class loadedMyClass = classLoader.loadClass(className);
            Constructor constructor = loadedMyClass.getConstructor();
            Object myClassObject = constructor.newInstance();
            return myClassObject;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}


TestMaker类

package test.maker;

import test.api.IQuestion;
import test.api.IQuestionFactory;
import test.api.ITestSet;
import test.util.MyClassLoader;

public class TestMaker {
    public static void main (String[] args){

        MyClassLoader cl = MyClassLoader.instance;

        IQuestionFactory factory = (IQuestionFactory) cl.createInstance("test.api.IQuestionFactory");
        ITestSet testset = factory.makeEmptyTestSet();

        String question = "Which of the following people was not a US president?";
        String[] choices = {"George Washington", "Benjamin Franklin", "Andrew Jackson", "Mr. Rodgers"};
        int answer = 1;

        IQuestion q = factory.makeMultipleChoice(question, choices, answer);
        testset.add(q);

        factory.save(testset,"Questions");

    }
}


IQuestionFactory接口

package test.api;

import java.io.IOException;


public interface IQuestionFactory {
    /**
     * @param question The question
     * @param choices The choices as an array
     * @param answer The index to the answer in the choices array
     * @return An instance of a multiple choice question.
     */
    public IQuestion makeMultipleChoice(String question, String[] choices, int answer);


    /**
     * @param question The question.
     * @param answer The answer
     * @return an instance of a true-false question
     */
    public IQuestion makeTrueFalse(String question, boolean answer);

    /**
     * @param question The question, including the blanks
     * @param answers Array of answers to the blanks
     * @return an instance of a fill-in-the-blank question
     */
    public IQuestion makeFillInBlank(String question, String [] answers);

    /**
     * @param question The question.
     * @param keywords The answers as a list of key words.
     * @return an instance of a short answer question.
     */
    public IQuestion makeShortAnswer(String question, String[] keywords);

    /**
     * @param filename The file containing the test set.
     * @return A Test set
     * @throws IOException if can't load the file.
     */
    public ITestSet load(String filename);


    /**
     * @param testSet The test set to be stored.
     * @param filename  The filename to be used.
     * @return true if save is successful
     * @throws IOException if unable to save the test set.
     */
    public boolean save(ITestSet testSet, String filename);


    /**
     * Create an empty test set.
     *
     * @return an empty test set.
     */
    public ITestSet makeEmptyTestSet();


}

最佳答案

您正在尝试创建接口实例,这没有任何意义。您只能创建一个类的实例。您需要使用另一个类来实现接口,并将该类用作cl.createInstance的参数。

编辑:虽然说实话我完全不知道您为什么在这里使用反射。您可能应该这样做:

IQuestionFactory factory = new MyQuestionFactory()


MyQuestionFactory实现IQuestionFactory的位置。这样更有效,然后编译器会捕获您的错误。您现在正在做的是:

IQuestionFactory factory = new IQuestionFactory()


编译器会抓住这一点。

08-16 11:29