Why do we need "? extends" in Java
stackoverflow.com
stackoverflow.com
So, to cite the textbook example, say you are implementing a Stack<E>. It will probably have the methods:
public void push(E element);
public E pop();
and, for convenience: public void pushAll(Iterable<? extends E> elements);
public void popAll(Collection<? super E> destination);
The pushAll has "? extends" because the elements Iterable will "produce" elements for the stack. The popAll has super because the destination Collection will "consume" elements from the stack. It is not that hard, is it? Let's note that guard-of-terra is talking about proficiency, not mere familiarity. I believe reading "Effective Java" is a nice way to get closer to the proficient level.Let it be noted that this whole mess exists because generics in Java were implemented with type erasure so their introduction wouldn't break legacy code. I personally think this was a bad idea, but it does show that when a language is evolving, there are a bunch of constraints the designers must be aware of.
[1] http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp...
I think the mistake the Java designers made here was going with use-site variance instead of definition-site variance.
On the other hand, sometimes I think an unsound type system with List<String> being a subtype of List<Object> would be better than what we have today, for pragmatic reasons. Of course, I think this makes me a non-type-theorist, as what I'm saying is considered heresy in some circles [1].
[1] http://lambda-the-ultimate.org/node/4377 (search for unsound).
On the other hand, if your structure is immutable it would probably work.
I hope when writing Java code sometimes at a job, I can refer to this again.
This is all done in the name of type safe programming (I don't know the exact english terminology).
<? extends B> is called covariance. It helps to access attributes of B and derived classes with get() but prevents to use set().
ArrayList<? extends Number> list;
list = new ArrayList<Integer>();
list = new ArrayList<Double>();
list = new ArrayList<Long>();
list.set(index, myInteger); // throws error
Compiler has to know the exact type to set the value, but Long, Double and Integer are all from type Number, so you can read it into a Number variable.
Is that correct?
List<Shape> is not a "list of Shapes", it's a "list parametrized with Shape"
List<? extends Shape> is a "list parametrized with something that extends Shape"
e.g. you can assign it with List<Circle> (you can't assign it to List<Shape> since Shape != Circle) and then you can do operations on it that would not break List<Circle> (can't put Square in it)
It's hard to say that the JVM is faster or slower than X because it usually comes down to the way in which the application is developed.
If C++ was ALWAYS faster then I wouldn't be using Java for our trading systems. Some of our competitors use C++ and some use Java. We have one of the fastest trading platforms in the world, the only firm to have faster than us are also using Java.
I used to work at a world leading investment bank who's entire low latency, high scalable trading platforms were built in Java.
Just about every large financial firm that I've worked at plus both telco firms and one management consultancy used Java to build large, fast and scalable applications.
You may have no use for Java in your small bubble of a world where you most probably work on insignificant, crappy pay and waste of time projects, but people who work on important stuff in the real world do. I'm sure other people can tell you why Java is important in ways that I cannot. I just get annoyed when I see people slag off a piece of technology just because they don't use it or like it.
How about that?
Have you tried programming BEFORE Java, when the same kind of systems were done in C++ with CORBA or similar monstrosities?
In Python, the deploy/run unit tests/spot typo cycle greatly slows me down.
The "? extends" is not an "extra verbosity". It's actually a sound CS concept, one that you need to make compiler understand how some generic code turns out to be correct while working on partially specified types.
IIRC C# didn't have that "extra verbose" thing in its early versions and the developers weren't very happy because you do need it.
Not being able to separate "extra verbosity" from "solid CS concepts" makes you lousy at reasoning about programming languages. Might as well stop bothering.