生成独特的自动递增的实例ID
我一直在试图生成从1开始,像这样的类实例的唯一ID:生成独特的自动递增的实例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
。
不是真的!有几件事你可以尝试:
- 有一个单一的
IDGenerator
类与静态方法来生成一个特定的类的新ID。.generate()
方法将采用Class<?>
参数,并将映射类保留到最近给出的标识符。这将把所有的逻辑放到一个类中,但不会真正简化。 - 在每个想要使用这种行为的类中有一个
IDGenerator
类的新实例的静态引用。在这种情况下,IDGenerator
类不需要Class<?>
参数,因为每个使用它的类都有一个实例。其方法.generate()
将是一种无参数方法。再次,我不确定这会让事情变得更简单。 - 放弃连续ID的要求。这样,你可以有一个类
IDGenerator
与静态无参数.generate()
方法,它只是放弃下一个未使用的标识符。然后,您的标识符在您的应用程序中将是唯一的,而不是在班级中连续使用。
你有什么是相当傻瓜和苗条。
还有一点小问题:你说你想让你的ID从0开始,但是你写它的方式,他们将从1开始。你想要this.id = ID++
而不是this.id = ++ID
。
这是一个错误。我的意思是他们打算从1.开始编辑。并且感谢您理解我的意思,即使我不明确含糊。我真的希望我可以放弃你的答案。 – RedCat23 2014-11-04 22:05:28
@ RedCat23你还没有足够的代表upvote,但如果它是有用的(这也会给你一些代表点),请点击勾来标记为接受的答案。 – 2014-11-04 22:18:46
正如其他人所指出的,这可能不是一个好主意。但是,如果你想要做的只是递增基类构造函数的计数器:
abstract class foo {
static int globalId = 0;
final int id;
foo() {
id = globalId;
++globalId;
}
}
使用的AtomicInteger如果线程安全性是一个问题。
如果我只增加基类中的计数器,那么所有的子类将使用相同的'globalId'共享相同的ID生成。这不是我需要的。 – RedCat23 2014-11-04 21:52:07
是的,所有人都会共享相同的身份证号码,但每个班级将获得唯一的身份证件。 globalId是静态的,所以整个程序只有一个。您的问题表明您需要保证的是分配给每个实例的唯一编号,并且这样做。这听起来也许你的要求更具体:每个子类具有对子类**唯一**的整数,并且对于每个子类,整数开始和0并且没有间隙。那是你需要的吗? – 2014-11-04 21:54:41
是的,这就是我需要的,每个子类的ID都是连续的。抱歉含糊不清。编辑的问题。 – RedCat23 2014-11-04 22:04:08
一种选择,使用的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));
}
可能重复[Java的给予对象的每个实例的唯一编号(http://stackoverflow.com/questions/21708765/java-give-每个对象一个唯一编号) – 2014-11-04 21:33:31
不,它通常是按类(或类的层次结构)进行的。而且你不应该抽象类,因为你需要一个计数器 – 2014-11-04 21:34:24
@RC。这不是该问题的重复。这个问题是关于如何在多个类中重用(已经理解的)行为。 – 2014-11-04 21:40:55