【发布时间】:2014-03-03 00:25:44
【问题描述】:
据我所知,Java 泛型中的静态字段在所有实例之间共享,而与类型参数无关。比如在下面的类中
class A<T> {
static String s;
}
字符串 s 将在 A 的所有实例之间共享,而与 T 无关。
我想参数化 T 上的静态字段(和相关的一次性操作),以便在上面的示例中,String s 在 A
到目前为止,我能够提出以下解决方案:
static class Rec {
private Class<?> clazz;
private String name;
public Rec(Class<?> clazz, String name) {
this.clazz = clazz;
// parameterized, quasi-static field
this.name = name;
}
protected Class<?> ofClass() { return clazz; }
protected String ofName() { return name; }
}
static abstract class Base<T> {
private static List<Rec> derived = new ArrayList<Rec>();
private Class<T> type;
public Base(Class<T> type, String s) {
this.type = type;
for (Rec rec : derived) {
if (rec.ofClass() == type) return;
}
Rec rec = new Rec(type, type.getName());
derived.add(rec);
System.out.println("Added " + rec.ofName());
}
protected String getName() {
for (Rec rec : derived)
if (rec.ofClass() == this.type) return rec.ofName();
return null;
}
}
static class Test1 extends Base<Test1> {
public Test1() {
super(Test1.class, Test1.class.getName());
}
}
static class Test2 extends Base<Test2> {
public Test2() {
super(Test2.class, Test2.class.getName());
}
}
Test1 t1 = new Test1();
System.out.println(t1.getName());
Test2 t2 = new Test2();
System.out.println(t2.getName());
Test2 t3 = new Test2();
System.out.println(t3.getName());
此代码在基类的每个派生类型记录列表中创建准静态字段的单独实例。因此,两个单独的类名“Test1”和“Test2”被打印到控制台;但是,t2 和 t3 实例共享相同的名称字段。
虽然基类在编译时不知道它的派生类,但它是在运行时,这可能并不像应有的那样干净。此外,每次调用使用参数化准静态字段的基方法时,都会对列表进行线性搜索以找到对应的类型。
有没有更有效、更惯用的方式来做到这一点?
【问题讨论】:
-
为什么不使用地图而不是列表来避免线性搜索?
标签: java generics static field