简体   繁体   中英

In Java, how can I implement a non-generic interface which has methods that use generics using concrete types?

I have an interface...

public interface ApiClient {
    <T> void updateData(List<T> data);
}

and two implementations of that interface...

public class Version1ApiClient implements ApiClient {
    public <Version1DataContract> void updateData(List<Version1DataContract> data) {
        // ...
    }
}
public class Version2ApiClient implements ApiClient {
    public <Version2DataContract> void updateData(List<Version2DataContract> data) {
        // ...
    }
}

I get this error in both of the implementations...

Type parameter 'Version#DataContract' hides visible type 'com.company.package.Version#DataContract'

...where the # is the number for that respective implementation.

What have I done wrong? Also, in this use case the interface cannot have a type parameter on it directly. It can only be on the method.

You didn't do much that's wrong; but you skipped a naming convention - but that could be hiding a more important misunderstanding

What do you think <Version1DataContract> does here?

public <Version1DataContract> void updateData(List<Version1DataContract> data) {
    // ...
}

Do you think it makes updateData work just with Version1DataContract , which is a class on your classpath and imported in the source file of your Version1ApiClient class? If your answer is yes, then you're mistaken. That code is equivalent to:

public <T> void updateData(List<T> data) {
    // ...
}

<Version1DataContract> is just a weirdly named type variable.

Now, about your question... The problem is that you have declared <Version1DataContract> as a type variable on a method, while there is an imported type called Version1DataContract , and that is already visible. This is a warning alerting you to potential bugs.


To address what seems to be your main issue, if you need Version1ApiClient to limit <T> void updateData(List<T> data); to T=Version1DataContract , you can't do it without changing the interface. You'd have to change your interface and broaden the scope of T so that the subclass can "freeze" it:

interface ApiClient<T> {
    void updateData(List<T> data);
}

class Version1ApiClient implements ApiClient<Version1DataContract>  {
    public void updateData(List<Version1DataContract> data) {
        // ...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM