The constructor of Plane in your call takes a List<Points<? extends Float>>, but you are passing it a List<Points<Float>>.
The relationship between Points<? extends Float> and Points<Float> is exactly like that of Number and Integer - one is the subtype of another. Compare:
// in both cases, you are assigning an instance of a subtype to a variable of a supertype
Points<? extends Float> p = new Points<Float>();
Number n = Integer.valueOf(1);
So trying to pass (or implicitly convert) a List<Points<Float>> into a List<Points<? extends Float>> is just like trying to do that with a List<Integer> and List<Number>. As you probably know already, it doesn't work at all because allowing you to do this would make it unsafe to add things into the list:
List<Integer> integers = new ArrayList<>();
List<Number> numbers = integers; // suppose this is allowed...
numbers.add(0.1f); // I can now add a float into the integer list!
In practice though, I think the same thing cannot happen with List<Points<? extends Float>> and List<Points<Float>>, because it is not possible to create another concrete subtype of Points<? extends Float> that is also not a subtype of Points<Float>. This is mainly because Float is final. However, the Java compiler isn't designed to see this.
List<Points<Float>> floatPoints = new ArrayList<>();
List<Points<? extends Float>> extendsFloatPoints = floatPoints; // suppose this is allowed
extendsFloatPoints.add(/* whatever you can add here can be added to floatPoints */);
One way to fix the error, is as you have found, to add ? extends. In your case, this means:
private List<? extends Points<? extends T>> points;
public Plane() { }
public Plane(List<? extends Points<? extends T>> points) {
this.points = points;
}
Note that this is in addition to the ? extends in the type parameter of Points. This is analogous to turning List<Number> numbers = new ArrayList<Integer>(); into List<? extends Number> numbers = new ArrayList<Integer>();
This essentially prevents you from adding anything into the list except nulls.
Another way to solve the problem is to create a List<Points<? extends Float>> from the very beginning and pass that into the constructor. It is totally possible to do:
List<Points<? extends Float>> lp = new ArrayList<>();
lp.add(new Points<Float>(1f, 2f));
// add more points...
Plane<Float> plane = new Plane<>(lp);
A third way is to just get rid of all the wildcard all together, and just use List<Points<T>> everywhere. I don't see much value in using them, since most of the Number subclasses are final anyway.