Java实例化通用hashmap值

时间:2014-12-16 00:27:25

标签: java generics

我有以下java代码

public class QuestionBuilder {

private QuestionBuilder(){}

static HashMap<Long,Class<? extends Question>> questionIdMap;

static{
    questionIdMap = new HashMap();
    questionIdMap.put(1L, LicenseNumberQuestion.class);
    questionIdMap.put(2L, USPQuestion.class);
}



static Question getQuestion(long questionId)
{
    if(!questionIdMap.containsKey(questionId))
    {
        throw new BusinessProfileInputException("Add an id to question class map entry");
    }

     return questionIdMap.get(questionId).newInstance();

}

}

我希望我的getQuestion方法能够返回一个新的类实例,该实例在地图中指定为通过我的代码预期的值。 Howerver最后一行代码无法编译:

return questionIdMap.get(questionId).newInstance();

我是否错误地想到了这个?即有更好的方法来解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

你只需要捕获一个例外:

try {
    return questionIdMap.get(questionId).newInstance();
} catch(InstantiationException e) {
    System.out.println("Constructor failed: );
    e.printStackTrace();
    return null;
}

这应该编译得很好。

答案 1 :(得分:0)

我会这样做:

public final class QuestionBuilder {

    private QuestionBuilder(){}

    public enum Type {

        LICENSE_NUMBER {
            @Override
            Question getQuestion() { return new LicenseNumberQuestion(); }
        },
        USP {
            @Override
            Question getQuestion() { return new USPQuestion(); }
        };

        abstract Question getQuestion();
    }

    public static Question getQuestion(Type type) {
        return type.getQuestion();
    }
}

使用您的解决方案,该类用户必须编写

Question question = QuestionBuilder.getQuestion(1);

这并不是很好,因为它不清楚是什么&#34; 1&#34;这意味着,她将不得不学习一大堆数字的含义。另外,如果你输入一个并不代表任何内容的数字,那么就会出现问题(因此需要BusinessProfileInputException)。

使用enum方法,该类的用户将编写

Question question = QuestionBuilder.getQuestion(QuestionBuilder.Type.LICENSE_NUMBER);

现在这显然更长,但有三大优势。 (1)班级用户不需要记住任何抽象代码。实际上,如果用户使用的是体面的IDE,那么在她输入时,实际上应该向她提供一个有意义的选择列表。 (2)不再需要BusinessProfileInputException因为现在不可能传递的东西并不代表任何东西(null除外),但在此案例a NullPointerException无论如何都会被抛出)。 (3)您不再需要反射来创建新的Question,因此不需要恼人的try阻止。

但它甚至比这更好。您注意到,由于我们已经摆脱Map,因此课程QuestionBuilder实际上并没有任何。您可以通过完全删除课程来进一步改进,并使enum成为顶级课程,使用简单的名称TypeOfQuestion。然后所有用户都必须输入

Question question = TypeOfQuestion.LICENSE_NUMBER.getQuestion();
Java中的

enum非常棒。它们远远优于其他语言的同行。我强烈建议您了解它们。