I have this two interfaces and classes:
public interface Identifiable<T> {
T getId();
}
public interface GenericRepository<T extends Identifiable<K>, K> {
T get(K id);
}
public class MyEntity implements Identifiable<Long> {
private Long id;
public Long getId() {
return id;
}
}
public class MyService {
private GenericRepository<MyEntity, Long> myEntityRepository;
}
It all works as desired. But in my opinion second generic parameter in GenericRepository (K) is redundant. Because I know that MyEntity is an Identifiable, I think it would be great if I can finally use it like this:
public class MyService {
private GenericRepository<MyEntity> myEntityRepository;
}
But I’m trying different things without succeeding. Is it possible? If not, why not?
UPDATE: Answering some responses. I think compiler knows something about which type is the generic in MyEntity. For example:
public class MyEntityGenericRepository implements GenericRepository<MyEntity, Long> {
// compiles...
}
public class MyEntityGenericRepository implements GenericRepository<MyEntity, String> {
// compiler says: "Bound mismatch: The type MyEntity is not a valid substitute for the bounded parameter <T extends Identifiable<K>> of the type GenericRepository<T,K>"
}
I don’t think you can omit it. With
T extends Identifiable<K>you want to say that the generic type parameter must be anIdentifiable. SinceIdentifiableis a generic class, you need to mention its generic type parameter too (if you want to play by the rules that is – if you omit it, you lose all generic type safety forGenericRepository, due to backward compatibility rules). Note also thatKis actually used as the parameter type ofGenericRepository.get. And since that type may be different fromT, you need to satisfy the compiler by declaring it as another generic type parameter ofGenericRepository. Otherwise the compiler has no way of knowing whatKis.