0

我已经问过类似的问题,但我没有得到答案,所以我试图直接在这里并提供尽可能多的细节。基本上我有5个类,其中一个扩展了JFrame ,它是名为TigBase的主类,第二个扩展了JPanel,它被称为Cont,第三、第四和第五个没有扩展,但它们具有相同的方法:

public void paintah(Graphics g){
       g.fillRect(20,20,20,20);

所以JPanel应该绘制它的图形。但我们也不知道这些类的名称。类的名称作为公共 var存储在Cont类中

public static ArrayList<String> classes = new ArrayList<String>();

所以我也有一个方法:

public void paintComponent(Graphics g){

是的,这些类的实际名称是Cutscene0、Cutscene1、Menu2 我希望Cont类绘制它们的图形,但无法做到这一点。如果我“知道”类的名称,我会这样做:

Cutscene0 cut = new Cutscene0();
public void paintComponent(Graphics g){
       super.paintComponent(g);
       Cutscene0 cut = new Cutscene0();
       cut.paintah(g);

但是我可能有更多相同类型的未知类,所以我需要将它们存储在 arraylist 中。我确实试过这个:

for(int i = 0; i<classes.size;i++){
    Class.forName(classes.get(i)).getMethod("paintah", Graphics.class).invoke(g);

但这给了我一个例外

java.lang.IllegalArgumentException: java.lang.ClassCastException@2c80fb85

所以,是的,我真的需要解决它,我整天坐着研究如何做到这一点并尝试了不同的东西,但它们只是不起作用..希望你能帮忙!

4

2 回答 2

3

这是javadoc Method.invoke()

public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

在具有指定参数的指定对象上调用此 Method 对象表示的基础方法。

(强调我的)。

您的“传统”方法调用看起来像

Cutscene0 cut = new Cutscene0();
cut.paintah(g);

要使用反射做同样的事情,你必须因此

  • 通过调用无参数构造函数创建类的实例
  • 调用此实例上的方法

所以你会有类似的东西

Class<?> clazz = Class.forName(classes.get(i));
Object cut = clazz.newInstance(); // no-arg constructor
Method method = clazz.getMethod("paintah", Graphics.class);
method.invoke(cut, g); // invoke the method on cut, with g as parameter

也就是说,您没有说明为什么您不知道类名。我有一种感觉,一个合适的 OO 模式,就像一个工厂,可以让事情变得更清晰。至少,您的所有类都可以实现相同的接口Painter,然后您就可以这样做

Class<?> clazz = Class.forName(classes.get(i));
Painter cut = (Painter) clazz.newInstance(); // no-arg constructor
cut.paintah(g);
于 2013-07-23T09:08:01.777 回答
0

关于您的例外:来自Method javadoc

Method 允许在将要调用的实际参数与底层方法的形式参数匹配时发生扩大转换,但它会抛出一个IllegalArgumentExceptionif a narrowing conversionwould occur。

但无论如何,我认为如果可以的话,你应该避免反射,并使用接口而不是字符串类名:

interface Paintable {
  public void paintah(Graphics g)
}

public static ArrayList<Paintable> ps = new ArrayList<Paintable>();

for(int i = 0; i<ps.size;i++){
    ps.get(i).paintah(g)
}
于 2013-07-23T09:07:56.623 回答