Reputation: 159
I have been trying to generate unique IDs for class instances starting from 1, like so:
public abstract class foo {
static int ID = 0;
final int id;
public foo() { this.id = ++ID; }
}
I then realised that I have several classes that require this behaviour, and so I tried to make an abstract class
from which to inherit, but I found that static
fields can't really be inherited.
Is there any way I can reuse this common behaviour in Java?
Edit:
I did not make it clear, but I need the indexes for each subclass to be not only unique, but also consecutive.
For example, if I have bar
and baz
inheriting from foo
:
bar b1 = new bar();
baz b2 = new baz();
bar b3 = new bar();
b2
should have id == 1
, and b3
should have id == 2
.
Upvotes: 3
Views: 4109
Reputation: 20370
One option, use UUIDs (http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html)
UUID.randomUUID();
A second option is to just use AtomicInteger for this:
AtomicInteger idGen = new AtomicInteger();
System.out.println(String.format("First is %d", idGen.getAndIncrement()));
System.out.println(String.format("Second is %d", idGen.getAndIncrement()));
I would not use abstract classes or inheritance or even custom classes for this issue.
EDIT: Here is a full example that supports the initial code. I don't see how you could make this simpler:
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));
}
Upvotes: 0
Reputation: 20520
Not really! There are a couple of things you might try:
IDGenerator
class with a static method to generate a new ID for a specific class. The .generate()
method would take a Class<?>
parameter, and would maintain a HashMap
mapping classes to most recently given out identifiers. This would put all the logic into one class, but wouldn't really simplify things.IDGenerator
class inside each class that wants to use this kind of behaviour. In this case, the IDGenerator
class wouldn't need a Class<?>
parameter because there would be one instance for each class using it. Its .generate()
method would be a no-arg method. Again, I'm not sure this makes things much simpler.IDGenerator
with a static no-arg .generate()
method that would just dish out the next unused identifier. Your identifiers would then be unique across your application, and not consecutive within a class.What you've got is pretty fool-proof and slimline.
One more minor note: you say you want your IDs to start from 0, but the way you've written it, they'll start from 1. You want this.id = ID++
rather than this.id = ++ID
.
Upvotes: 1
Reputation: 9953
As others have noted, this may not be a good idea. However, if you want to do it just increment the counter in the base class constructor:
abstract class foo {
static int globalId = 0;
final int id;
foo() {
id = globalId;
++globalId;
}
}
Use an AtomicInteger if thread safety is a concern.
Upvotes: 1