Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redundant generic parameters

Tags:

java

generics

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>"
}
like image 751
sinuhepop Avatar asked Mar 13 '12 12:03

sinuhepop


People also ask

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

How many type parameters can be used in a generic class?

You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.


1 Answers

I don't think you can omit it. With T extends Identifiable<K> you want to say that the generic type parameter must be an Identifiable. Since Identifiable is 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 for GenericRepository, due to backward compatibility rules). Note also that K is actually used as the parameter type of GenericRepository.get. And since that type may be different from T, you need to satisfy the compiler by declaring it as another generic type parameter of GenericRepository. Otherwise the compiler has no way of knowing what K is.

like image 190
Péter Török Avatar answered Sep 28 '22 20:09

Péter Török