Chcę stworzyć generator IDków, który może być sparametryzowany np. Longiem lub Integerem.
final class IdGenerator<ID extends Number> {
private ID id;
IdGenerator() {
System.out.println(this.id instanceof Long);
System.out.println(this.id instanceof Integer);
if (id instanceof Long) {
id = (ID) Long.valueOf(0L);
} else if (id instanceof Integer) {
id = (ID) Integer.valueOf(0);
} else {
throw new RuntimeException("Invalid ID type (must be Long or Integer)");
}
}
ID nextId() {
if (id instanceof Long) {
id = (ID) Long.valueOf(id.longValue() + 1L);
} else if (id instanceof Integer) {
id = (ID) Integer.valueOf(id.intValue() + 1);
} else {
throw new RuntimeException("Invalid ID type (must be Long or Integer)");
}
return id;
}
public static void main(String[] args) {
IdGenerator<Integer> longIdGenerator = new IdGenerator<>();
Integer id = longIdGenerator.nextId();
}
}
Po uruchomieniu tego kodu wywala wyjątek w konstruktorze, bo id
jest nullem więc instanceof
zwraca false
.
IdGenerator
siedzi w innej generycznej klasie, a na szczycie hierarchii wygląda to tak:
public class InMemoryBookRepository extends InMemoryCrudRepository<BookEntity, Long> implements BookRepository {
}
Zatem odpada:
- przekazanie argumentu określającego typ (np.
Long.class
) - przekazanie do konstruktora początkowej wartości
Cały problem sprowadza się do tego, żeby w konstruktorze jakoś zainicjalizować pole id
odpowiednią wartością.
Wiem, że w runtime nie ma informacji o typie, jakim została sparametryzowana klasa, da się to jakoś "obejść"?