【问题标题】:Call random method of random class in java在java中调用随机类的随机方法
【发布时间】:2012-08-28 06:25:09
【问题描述】:

我正在开发一个培训课程,该课程有一个 Training 课程,其函数返回一个随机方法(一种练习类型)。

这个通用类由一些特定类扩展,其中包含不同类型的练习。

然后我创建一个特定类的数组,并想随机选择一个,然后调用随机练习方法。

这是泛型类

public class TrainingClasses {
Method[] mMethods;
Random randomGenerator; 
 public void TraningClasses() {
    randomGenerator = new Random();

    /* Store methods */
    mMethods= getClass().getDeclaredMethods();


}

 public void RandomExercise() {
    Random randGenerator = new Random();
    int rnd = randGenerator.nextInt(mMethods.length);

mMethods[rnd].invoke(this);

}

这是一个具体培训班的例子

 public class MatheMagic extends TrainingClasses{


public MatheMagic() { 
/*Something*/
 }



public String[] SomeExercise() { 
    /*Some code */
 }

public String[] SomeOtherExercise() { 
    /*Some code */
 }      
}

在主要活动的这一点上,我想这样做:

private Object[] mTrainingClasses; 
private MatheMagic mMathMag;
/*eventually other training classes*/
mMathMag = new MatheMagic();
mTrainingClasses[0] = mMathMag;

Random randGenerator = new Random();
int rnd = randGenerator.nextInt(mTrainingClasses.length);
Object aTrain = mTrainingClasses[rnd];

/*Return exercise*/
String[] mRes = aTrain.RandomExercise();

这是代码的相关部分,现在仍然不完整......但是当我尝试存储动态调用方法的结果时,由于出现类型不匹配错误,我无法继续。 可能是项目结构不对,应该改用别的架构……不过,目前还没有找到更好的办法。

感谢任何能够提供帮助的人。

––––––––––––––––––––––––––––––––––––––––––––––––––––

谢谢大家的回答。 以下是可能需要的人的最终工作代码:

/** Common interface for all exercises */ 
public interface Exercise {
  public String[] run();
} 



/** Common interface for all training classes */
public abstract class TrainingClass {

  private Random rand = new Random();
  public ArrayList<Exercise> mExerciseTypes = new ArrayList<Exercise>();

  /** Run a random exercise */
  public String[] runRandomExercise() {
    int i = rand.nextInt(mExerciseTypes.size());
    return mExerciseTypes.get(i).run();
  }

}


/*Specific training class*/

public class MatheMagic extends TrainingClass {

 public MatheMagic() {

        class SomeExercise implements Exercise {

            public String[] run() {

                 String[] mRes = new String[2];
                  mRes[0] = "Question type 1";
                  mRes[1] = "Answer type 1";
                return mRes;
            }

        }

        class SomeOtherExercise implements Exercise {

            public String[] run() {

                 String[] mRes = new String[2];
                  mRes[0] = "Question type 2";
                  mRes[1] = "Answer type 2";
                return mRes;
            }

        }
        SomeExercise mN = new SomeExercise();

        SomeOtherExercise mS = new SomeOtherExercise();

        mExerciseTypes.add(mN);
        mExerciseTypes.add(mS);
 }

}

【问题讨论】:

  • 首先,所有TrainingClass子类都应该实现一些接口,然后访问,然后不应该有任何类转换错误。
  • 您可能正在尝试调用带有一些参数的方法。整个信息是什么?你能打印出错误发生时你试图调用的方法吗?
  • String[] mRes = aTrain.RandomExercise(); aTrain 是一个对象,所以如果没有演员表,我猜 RandomExercice() 的调用就无法工作

标签: java class dynamic reflection


【解决方案1】:

我认为您可能应该重新考虑您的设计。在大多数情况下,通常应避免使用反射。只有在动态加载和执行代码时才真正需要反射(例如,JUnit 框架在名称作为命令行参数传递的类中动态加载和执行测试)。

我建议不要在一个类中随机执行一个方法,而是创建一个具有公共接口的Exercise 对象集合,随机选择其中一个然后运行它。这是我在想的一些骨架代码:

import java.util.ArrayList;
import java.util.Random;

/** Common interface for all training classes */
public abstract class TrainingClass {

  private Random rand = new Random();
  protected ArrayList<Exercise> exercises = new ArrayList<Exercise>();

  /** Run a random exercise */
  public String[] runRandomExercise() {
    int i = rand.nextInt(exercises.size());
    return exercises.get(i).run();
  }

}

/** Common interface for all exercises */ 
public interface Exercise {
  String[] run();
}

public class MatheMagic extends TrainingClass {

  /** Constructor creates all the exercises */
  public MatheMagic() {
    // Some exercise
    exercises.add(new Exercise {
      public String[] run() {
        // Code for some exercise ...
      }
    });
    // Some other exercise
    exercises.add(new Exercise {
      public String[] run() {
        // Code for some other exercise ...
      }
    });
    // etc ...
  }

}

由于所有练习都是Exercise 类型并且有一个通用的run() 方法,因此不需要使用反射。声明有点冗长,因为您需要为每个练习创建一个 anonymous inner class,但为了避免反思,额外的冗长是值得的!

【讨论】:

  • 这看起来很棒!我发现了几个问题:我必须将练习从受保护更改为公开,并明确声明实现练习的类,以避免语法错误。我不确定,但可能是 Eclipse 很挑剔吗?但是,这没什么大不了的,这解决了问题,非常感谢您!我正在用工作代码编辑我的问题。
  • 太棒了!我很高兴你让它工作。我真的应该在我的帖子中添加免责声明,说明代码完全未经测试,可能存在语法错误。我很高兴你让它工作了!
【解决方案2】:

如果您手动创建训练类数组(即不是通过反射),您可以将保存类的数组类型更改为:

private TrainingClasses[] mTrainingClasses; 

以及你随机选择的班级类型:

TrainingClasses aTrain = mTrainingClasses[rnd];

这应该允许您在aTrain 上调用RandomExercise 方法。

【讨论】:

    猜你喜欢
    • 2013-07-10
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2012-09-27
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多