我有一个名为Packet
的课程和一个名为PacketClientConnecting
的课程。 PacketClientConnecting
和其他数据包的实例存储在ArrayList<Packet>
中。
我希望以static
和non-static
方式访问id值,例如PacketClientConnecting.getStaticId()
或packetArrayList.get(5).getId()
。
如果不在每个班级覆盖两个函数,我怎么能这样做?
答案 0 :(得分:0)
我认为没有一种非常流畅的方法可以做到这一点,但是你可以通过使用反射来实现你想要的东西(只有一次:在基类中):
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);
}
}
}