3

I'm trying to figure out why the compiler throws

test(capture<? extends Serializable>) in Predicate cannot be applied to (Serializable)

for test(e.getValue().getData()) and how I could solve the issue.

The code throwing the compiler error is the following

private Map<Predicate<? extends Serializable>, TaggedData<? extends Serializable>> scheduledData = new HashMap<>();

public synchronized <T extends Serializable> void conditionalSend(String tag, T data, Predicate<T> condition) {
    scheduledData.put(condition, new TaggedData<T>(tag, data));
    scheduledData.entrySet()
                 .stream()
                 .filter(e -> e.getKey().test(e.getValue().getData()))
                 .forEach(e -> send(e.getValue()));
}

My TaggedData class is defined like this

class TaggedData<T extends Serializable> implements Serializable {
    private static final long serialVersionUID = 1469827769491692358L;

    private final String tag;
    private final T data;

    TaggedData(String tag, T data) {
        this.tag = tag;
        this.data = data;
    }

    String getTag() {
        return tag;
    }

    T getData() {
        return data;
    }
}
succcubbus
  • 874
  • 1
  • 7
  • 24
  • I don't usually mess around with `?` in Generics, but isn't it forbidden to have a `?` in a Generic on the right side of an assignment? Which the `<>` operator implicitly is? – Powerlord Oct 21 '15 at 15:37
  • After the change I couldn't use my data in my predicate because it expected `? super Serializable`. As I keep the types in the map synchronous myself I now switched to a list of wrapper objects for Predicate and TaggedData. – succcubbus Oct 21 '15 at 16:20

1 Answers1

1

Imagine, that you pass Integer (which is Serializable) to Predicate<String> (which extends Serializable)? This is senseless.

Predicate#test() serves as a consumer, so you need to use Predicate<? super Serializable> instead.

Read more: What is PECS (Producer Extends Consumer Super)?

Community
  • 1
  • 1
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67