【问题标题】:Is it possible to call methods by name?是否可以按名称调用方法?
【发布时间】:2019-02-25 13:55:31
【问题描述】:

我正在构建一个小型测验应用程序,并将每个问题的每个答案存储在数据库表中(使用 JPA)。

我想知道是否有一种方法可以通过 for 循环动态获取 getter(例如使用 javascript),而不是必须写出每个 get 方法。

我的代码(其中“答案”是一个类,每个答案有 9 个不同的整数)。

public void parseUserScore(UserAnswers answer) {
    Integer[] answers = new Integer[] {
            answer.getQ1(),
            answer.getQ2(),
            answer.getQ3(),
            answer.getQ4(),
            answer.getQ5(),
            answer.getQ6(),
            answer.getQ7(),
            answer.getQ8(),
            answer.getQ9()
    };
    double totalscore = 0;
    Integer answeredQuestions = 0;
    for (int i = 0; i < answers.length; i++) {
        if (answers[i] > 0) {
            answeredQuestions++;
        }
        totalscore += answers[i];
    }
}

我的问题是是否可以通过这样的 foo 循环获取这些答案:

public void parseUserScore(UserAnswers answer) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 1; i < 10; i++) {
        String methodname = "getQ" + i.toString();
        list.add(i, answer.methodname)
    }   
}

这会更好,因为我想使用每个问题的索引根据它们各自的类别将它们分开。

【问题讨论】:

  • 为什么UserAnswers 不维护一个List&lt;Integer&gt; answers
  • 不,因为您的答案不在数组或列表中。您可以使用反射,但这是解决设计问题的糟糕方法。
  • 提示:一旦你开始编写代码,将事物命名为 a1、a2、a3,……你就做错了。然后你必须退后一步,弄清楚如何组织你的数据/代码以使用列表/数组。
  • 最好对问题使用数组,但我无法使用 JPA 进行映射以将各个列映射到 JPA 中的数组。所以我不得不将每一列映射到一个单独的整数......

标签: java methods metaprogramming


【解决方案1】:

根据您在问题中提供的内容,我认为您应该使用三个实体:UserQuestionAnswer。用户可以提出多个问题并提交多个问题的答案。一个答案总是属于一个问题。 JPA 有一些注解来模拟这些规则:

@Entity
class User {

    @OneToMany(mappedBy = "user")
    Set<Question> questions;

    @OneToMany(mappedBy = "user")
    Set<Answer> answers;

    // Getters & setters

}

@Entity
class Question {

    @ManyToOne
    @JoinColumn(name = "user_id")
    User user;

    @OneToMany(mappedBy = "question")
    Set<Answer> answers;

    // Getters & setters

}

@Entity
class Answer {

    @ManyToOne
    @JoinColumn(name = "user_id")
    User user;

    @ManyToOne
    @JoinColumn(name = "question_id")
    Question question;

    int score;

    // Getters & setters

}

之后,您可以简单地遍历特定用户的答案并计算总分:

final int totalScore = user.getAnswers().stream().mapToInt(Answer::getScore).sum();

请注意,这只是一个基本示例。您还应该考虑级联更新和获取关系的类型。

关于您对 for 循环的问题:Java 提供了一个名为“反射”的功能。它是一种元编程机制,可用于实现您所描述的。但是,这是一个坏主意,因为它有一些缺点,并且在您的情况下没有任何意义,因为用户应该能够回答超过 10 个问题。实际上,您无法知道用户将提交多少个答案。

【讨论】:

  • 是的,我打算发布一个带有反思的答案,并试图阻止 OP 使用它(通过像你所做的那样做),但现在你发布了这个,我只想支持你。但是,您应该添加为什么反射不是一个好主意(即使它在 cmets 中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2021-05-28
  • 2011-12-21
  • 2012-11-28
  • 2010-11-08
相关资源
最近更新 更多