简体   繁体   中英

How to use Guava functions declared for a generic super-type on a sub-type?

I know the title isn't terribly descriptive, but I couldn't really come up with something better. This is more about my (lack of) general understanding of generics than about Guava.

Let's suppose I have an interface like this:

public interface HasId {
  String getId();
}

And I have a function declared like this:

private static Function<? extends HasId, String> getId = new Function<HasId, String>() {
    public String apply(HasId input) {
        return input.getId();
    }
};

Why can't I use this function in eg an ordering like this (which generates a compiler error that getId is of the wrong generic type):

List<String> ids = ...;
List<SomeTypeImplementingHasId> someStuff = ...;
Ordering<SomeTypeImplementingHasId> byIds = Ordering.explicit(ids).onResultOf(getId);
List<SomeTypeImplementingHasId> sortedByGivenIds = byIds.sortedCopy(someStuff);

I know I can do it with a wrapper function casting it like this:

@SuppressWarnings("unchecked")
<T extends HasId> Function<T, String> getIdFunc() {
    return (Function<T, String>)getId;
}

But isn't there some way that doesn't need this unchecked cast?

Edit: This solved my problem, thanks @Natix & @Jean Logeart:

I first had to get rid of the wildcard in the function declaration:

Function<HasId, String> getId = ...

and then I had to change my ordering to be typed on the super-class also:

Ordering<HasId> byIds = Ordering.explicit(ids).onResultOf(getId);

You can:

  • Declare Function<HasId, String> getId = ...
  • Declare Function<? super HasId, String> getId = ... Function<? super HasId, String> getId = ...

More info: What is PECS (Producer Extends Consumer Super)?

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