我一直在尝试从1开始为类实例生成唯一ID,如下所示:
public abstract class foo {
static int ID = 0;
final int id;
public foo() { this.id = ++ID; }
}
然后我意识到我有几个需要这种行为的类,所以我尝试从中继承abstract class
,但我发现static
字段不能真正被继承。
我有什么方法可以在Java中重用这种常见行为吗?
编辑:
我没有说清楚,但我需要每个子类的索引不仅是唯一的,而且是连续的。
例如,如果我从bar
继承baz
和foo
:
bar b1 = new bar();
baz b2 = new baz();
bar b3 = new bar();
b2
应该有id == 1
,而b3
应该有id == 2
。
答案 0 :(得分:1)
正如其他人所说,这可能不是一个好主意。但是,如果您想这样做,只需在基类构造函数中递增计数器:
abstract class foo {
static int globalId = 0;
final int id;
foo() {
id = globalId;
++globalId;
}
}
如果担心线程安全,请使用AtomicInteger。
答案 1 :(得分:0)
不是真的!您可以尝试以下几种方法:
IDGenerator
类,以便为特定类生成新ID。 .generate()
方法将采用Class<?>
参数,并将为最近发出的标识符维护HashMap
映射类。这会将所有逻辑放在一个类中,但不会真正简化。IDGenerator
类的新实例进行静态引用。在这种情况下,IDGenerator
类不需要Class<?>
参数,因为每个类都有一个实例使用它。它的.generate()
方法将是一种无法使用的方法。同样,我不确定这会让事情变得更简单。IDGenerator
方法创建一个类.generate()
,该方法只会显示下一个未使用的标识符。您的标识符在您的应用程序中将是唯一的,而不是在类中连续的。你得到的是非常简单和细长的。
还有一个小注:您说您希望自己的ID从0开始,但是您编写它的方式,它们将从1开始。您需要this.id = ID++
而不是this.id = ++ID
。
答案 2 :(得分:0)
一个选项,使用UUID(http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html)
UUID.randomUUID();
第二种选择就是使用AtomicInteger:
AtomicInteger idGen = new AtomicInteger();
System.out.println(String.format("First is %d", idGen.getAndIncrement()));
System.out.println(String.format("Second is %d", idGen.getAndIncrement()));
我不会为这个问题使用抽象类或继承甚至自定义类。
编辑:这是一个支持初始代码的完整示例。我不明白你怎么能让这个更简单:
public static class foo {
final public int id;
foo(int id) { this.id = id; }
}
public static class bar extends foo {
static final AtomicInteger idGen = new AtomicInteger(1);
public bar() {
super(idGen.getAndIncrement());
}
}
public static class baz extends foo {
static final AtomicInteger idGen = new AtomicInteger(1);
public baz() {
super(idGen.getAndIncrement());
}
}
public static void main(String[] args) {
bar b1 = new bar();
baz b2 = new baz();
bar b3 = new bar();
System.out.println(String.format("b1.id = %d", b1.id));
System.out.println(String.format("b2.id = %d", b2.id));
System.out.println(String.format("b3.id = %d", b3.id));
}