如何根据类型通用调用方法?

时间:2010-11-18 13:15:41

标签: java generics reflection inheritance

请使用以下代码:

    public abstract class MySuperClass { 
       public abstract void update();
       /* ... */
    }

    public class A extends MySuperClass { 
       @Override
       public void update() { /* ... */ }
       /* ... */
    }

    public class B extends MySuperClass { 
       @Override
       public void update() { /* ... */ }
       /* ... */
    }

    public class Ticket<T extends MySuperClass> {
      private Class<T> c;
      public Ticket(Class<T> c){ this.c = c; }
      public Class<T> getClass() { return this.c; } 
      public void update() { /* HOW TO DO! */ }
      /* ... */
    }

    public class Main {
      public static void main(String[] args) {
        Ticket<A> myTicket1 = new Ticket<A>(A.class);
        Ticket<B> myTicket2 = new Ticket<B>(B.class);
        myTicket1.update();
        myTicket2.update();
      }
    }

如何根据其类型(AB)等升级故障单?

3 个答案:

答案 0 :(得分:4)

为什么Ticket知道更新实际意味着什么。它只需要将调用转发给MySuperClass的实例。泛型类的重点是泛型类可以处理任何对象(或对象的子集),而不必确切地知道它是什么类型。

public class Ticket<T extends MySuperClass> {
  private T thing;
  public Ticket(T thing) {
    this.thing = thing;
  }
  public void update() {
    thing.update();
  }
  /* ... */
}

答案 1 :(得分:0)

update()是一个实例方法,因此您需要一个实例来调用它。这可以通过

来实现
getClass().newInstance().update();

由于多态性,它将从A或B调用正确的方法。 但是要以更面向对象的方式解决它,你应该将一个实例传递给Ticket构造函数,然后调用update()。

答案 2 :(得分:0)

我已经调整了您的示例,以便更有意义......并实施update

public class Ticket<T extends MySuperClass> {
    private Class<T> c;
    private T t;

    public Ticket(Class<T> c) throws InstantiationException, IllegalAccessException { 
        this.c = c; 
        this.t = c.newInstance();
    }

    public Class<T> getClass() { 
        return this.c; 
    } 

    public void update() {
        t.update();
    }
    /* ... */
}

update方法调用t.update(),它将以多态方式调度update引用的实际对象的t方法。请注意,我添加了代码来创建和存储Class<T>

的实例

更新 - 我已将例外添加到Ticket构造函数中。这是使用反射创建实例所付出的代价的一部分......而不是使用new创建它们并将它们作为参数传递。