【问题标题】:Static and non static access to value静态和非静态访问值
【发布时间】:2013-07-10 17:11:24
【问题描述】:

我有一个名为Packet 的类和一个名为PacketClientConnecting 的类,它扩展了它。 PacketClientConnecting 和其他数据包的实例存储在ArrayList<Packet> 中。

我想以staticnon-static 方式访问id 值,例如PacketClientConnecting.getStaticId()packetArrayList.get(5).getId()

如何在不覆盖每个类中的两个函数的情况下做到这一点?

【问题讨论】:

  • 您面临的实际问题是什么?
  • 基类中能有List吗?
  • PacketClientConnecting.getStaticId() 有参数吗?它的类型是什么?如果 getStaticId(x) 只返回 x.getId(),那么您不必重写它。但这只是一个猜测,因为我不确定你想要完成什么。
  • 您面临的实际问题是什么?我必须在每个数据包类中复制两个函数(静态和非静态)。我认为这不是最好的方法。你能在基类中有 List 吗?没有。
  • ^PacketClientConnecting.getStaticId() 有参数吗?不,每个数据包只有一个 id。我想通过 class.getId() 或 instance.getId() 获取它。实例作为数据包存储在 ArrayList 中。

标签: java function casting static


【解决方案1】:

我不认为有一种非常流畅的方法可以做到这一点,但是可以通过使用反射来实现你想要的(只有一次:在基类中):

class Packet {

    public static int getStaticId() {
        return 1;
    }

    // This method is virtual and will be inherited without change
    public int getId() {
        try {
            // Find and invoke the static method corresponding 
            // to the run-time instance
            Method getStaticId = this.getClass().getMethod("getStaticId");
            return (Integer) getStaticId.invoke(null);

        // Catch three reflection-related exceptions at once, if you are on Java 7+,
        // use multi-catch or just ReflectiveOperationException
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

现在在子类中你只需要定义 getStaticId():

class PacketClientConnecting extends Packet {
    public static int getStaticId() {
        return 2;
    }
}

让我们测试一下:

class Main {
    public static void main(String[] args) {
        // Both print 1
        System.out.println(Packet.getStaticId());
        System.out.println(new Packet().getId());

        // Both print 2
        System.out.println(PacketClientConnecting.getStaticId());
        System.out.println(new PacketClientConnecting().getId());
    }
}

如果你想避免每次调用getId()时调用反射操作的开销,你可以使用基类中的一个字段来缓存id:

class Packet {

    public static int getStaticId() {
        return 1;
    }

    private final int id = computeId();

    public int getId() {
        return id;
    }

    // This method runs once per instance created
    private int computeId() {
        try {
            Method getStaticId = this.getClass().getMethod("getStaticId");
            return (Integer) getStaticId.invoke(null);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 2017-12-23
    • 1970-01-01
    相关资源
    最近更新 更多