如何在java中使用反射制作虚拟静态方法或功能等效方法

How to make Virtual static methods or a functional equivalent with reflection in java

我有一个抛射体类树,我试图使用一些反射来实现每一个可能的手工组合,当它大部分是复制粘贴或者最多是许多一行虚拟方法来覆盖属性时。

基本上,我有不同的武器类型,以不同的模式射击,如双联、交替或仅一种武器,以及许多不同的抛射物,如导弹、子弹、狙击手子弹。

当前的语法是:

1
2
3
4
public Bomber() {
    weapons.add(new TwinLinkedWeapon<Missile>(Missile.class));
    weapons.add(new Weapon<Bullet>(Bullet.class));
}

武器看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Weapon<T extends Projectile> {
    long lastShot;
    protected Constructor<? extends T> ctor;

    public Weapon(Class<? extends T> projectileType) {
        try {
            ctor = projectileType.getDeclaredConstructor(actor.Actor.class);
        } catch (SecurityException e) {
            e.printStackTrace();
            return;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return;
        }
        lastShot = 0;
    }

    protected long getLastShotTime() {
        return lastShot;
    }

    protected T newProjectile(actor.Actor ship){
        T projectile = null;
        try {
            projectile = ctor.newInstance(ship);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return projectile;
    }

    protected void setLastShotTime(long time) {
        lastShot = time;
    }

    public void shoot(Actor ship) {
        //calculates time passed in milliseconds
        if((System.currentTimeMillis() - getLastShotTime()) > T.getShotCoolDown()) {
            game.Game.getActors().add(newProjectile(ship));
            setLastShotTime(System.currentTimeMillis());
        }
    }

    public String getWeaponName(){
        return"" + getClass().getName() +"" + ctor.getName();
    }
}

我的问题很容易理解。在线if((System.currentTimeMillis() - getLastShotTime()) > T.getShotCoolDown())

T是一个抽象的抛射体类,而不是像子弹或导弹这样的派生类,所以当我调用静态方法T.getShotDelay()时,它总是调用Projectile.getShotDelay()而不是派生类。

我唯一的解决方案是用ctor创建一个t的实例,并使该属性基于实例而不是基于类,但这似乎是一个"不太理想"的解决方案。

我对Java反射是新的,我不确定语法来实现这一点。我将感谢您的任何意见。


您可以从Class对象中获取静态方法,并在null上调用它们,不需要调用构造函数。只需取T的运行时类,即:

1
2
3
4
T t = something;
Class<?> tClass = t.getClass();
Method staticMethod = tClass.getMethod("methodName");
staticMethod.invoke(null); // Static methods can be invoked on null.


您应该使用实例方法来获得您想要的功能。

也许你应该考虑使用抽象的工厂模式。

您可以拥有由MissileFactoryBulletFactory实现的IProjectileFactory接口。这些工厂能够制造新的射弹MissileBullet,实现IProjectile接口。当您创建新的武器实例(即new TwinLinkedWeapon(new MissileFactory()))时,会将射弹工厂作为参数提供。