Redundant generic parameters

后端 未结 6 1868
没有蜡笔的小新
没有蜡笔的小新 2021-01-12 03:36

I have this two interfaces and classes:

public interface Identifiable {
    T getId();
}

public interface GenericRepository

        
相关标签:
6条回答
  • 2021-01-12 04:08

    Why you cannot remove second K from,

    public interface GenericRepository<T extends Identifiable<K>, K> {
    

    So rather than having it as above, can we have it as

    public interface GenericRepository<T extends Identifiable<K>> {
    

    By this we can do what you want to do.

    0 讨论(0)
  • 2021-01-12 04:15

    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.

    0 讨论(0)
  • 2021-01-12 04:16

    Not much you can do, other than introduce an interface that just refines GenericRepository

      public interface LongKeyedRepository<T extends Identifiable<Long>> 
            extends GenericRepository<T, Long> { {
      //No new methods need to be defined
      }
    

    Then you can have

    private LongKeyedRepository<MyEntity> myEntityRepository;
    

    etc.

    0 讨论(0)
  • 2021-01-12 04:17

    It's not redundant from the standpoint of the GenericRepository class. When it has methods like T get(K id), it can't know which types of the id argument it can accept otherwise. You can write the following:

    interface GenericRepository<T extends Identifiable<?>> {
        T get(Object id);
    }
    

    Now you don't have to write Long as a type parameter, but you lose the possibility to check if the get method is used properly at compile time. So the type variable serves a specific purpose.

    And as for the field declaration, when you have a generic type, you have to specify all the type variables it uses. Of course, you could argue that it would be neat if the language could understand that one of the parameter values can be inferred from the other one, but it is debatable.

    0 讨论(0)
  • 2021-01-12 04:32

    It would work with (i.e. compile)

    public interface GenericRepository<T extends Identifiable> {
        T get(T id);
    }
    

    but it says nonetheless that Identifiable is a raw type and that it should be parametrized.

    Hope it helps.

    0 讨论(0)
  • 2021-01-12 04:33

    If I am not mistaken generics will all be compiled as if they were just Object. Now the syntax is (hard) checked to ensure that you are not putting apple with oranges because generics were added after the initial design of Java. this is why generics are so constrained...

    0 讨论(0)
提交回复
热议问题