0

I have the following piece of code:

public interface Segment<T> extends Period { ... };

public class SegmentImpl_v1<T> implements Segment<T> { ... };


public interface TimeLine<T, S extends Segment<T>> { ... };

public class TimeLineImpl<T, S extends Segment<T>>
        implements TimeLine<T, S> {

    private SortedSet<S> segments = new TreeSet<S>();

    public void someFunction() {

        // no suitable method for...
        segments.add(new SegmentImpl_v1<T>(...)); 

    }

}

and I get a no suitable method for... when adding a segment instance. It seems like Java's treeset does not apply the PECS principle. Is there a solution to this issue?

SOLUTION

I implemented:

public static <T> Segment<T> newItem(Period p, T itemValue) {
    return new SegmentImpl_v1(p, itemValue);
}

in SegmentImpl_v1 and call it in someFunction().

Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453

2 Answers2

1

Not seeing the relationship to PECS. Your troublesome code is not producing or consuming the generic collection. You're just working with it. The collection is type S. Of course you can't put a SegmentImpl_v1 into it. What if someone did this:

new TimelineImpl<Foo, SegmentImpl_v2<Foo>>  

Allowing a SegmentImpl_v1 in a SortedSet there is clearly incorrect.

Affe
  • 47,174
  • 11
  • 83
  • 83
  • But SegmentImpl_v1 implements Segment and S extends Segment, so don't they have Segment in common? – Jérôme Verstrynge Nov 05 '11 at 00:14
  • Certainly so they could both be in a `SortedSet>` safely, but there's no guarantee that v1 can safely be in a set of v2. What happens if you wanted to use a method unique to v2? – Affe Nov 05 '11 at 06:27
1

PECS has nothing to do with this. (You don't have any bounded wildcards.)

The problem is SegmentImpl_v1<T> is not a subtype of S. When you pass an argument to a method it must be a subtype of the declared type of the parameter.

newacct
  • 119,665
  • 29
  • 163
  • 224