Re: Returning a bounded wildcard type
markspace wrote:
I think in retrospect I'll go with this instead:
public interface MyMap {
class Node{
}
List<Node> getNodes();
List<Node> getAdjecientNodes( Node node );
float estimateCost( Node startNode, Node endNode );
}
since that doesn't use parameter types and still gets the job done with
out using wild cards. I have to change a couple of types in my
implementation, but I can still put a subclass of Node in a List<Node>
without doing anything risky, programmatically. I think this is the
better way to go.
Your solution is fine, but I'd like to discuss the difference between
'List <Node> nodes', 'List <? extends Node> nodes' and
'class Foo <N extends Node> { List <N> nodes; ... }'
(or the method-level equivalent,
'<N extends Node> void foo( List <N>
Your approach, 'List <Node>', claims that the 'List' homogeneously contains
'Node' elements, but each one could be of a different subtype of 'Node'. The
other two claim that the 'List' is homogeneously of some subtype of 'Node',
possibly 'Node' itself. You can read from or write to the 'List'.
'List <? extends Node>' claims that the element type is of some anonymous
subtype of 'Node'. You can read from the 'List' and reliably treat the
elements as 'Node', but you cannot insert into the 'List'. You cannot readily
make claims about the relationship between different "?" expressions, i.e.,
captures of 'Node'.
The last approach, 'List <N extends Node>', claims that the element type is of
a specific subtype 'N' of 'Node, that type determined by the client expression
that uses the class or method. You can read from or write to the 'List'. All
expressions within the class or method that refer to 'N' refer to the same type.
So given
public class Foo
{
public List <? extends Node> perform() {...}
public List <? extends Node> execute() {...}
}
you cannot know the relationship between the return element types of the two
methods within a specific 'Foo' instance, except that they are both possibly
different subtypes of 'Node'. But given
public class Foo <N extends Node>
{
public List <N> perform() {...}
public List <N> execute() {...}
}
you know for sure that both methods in the same instance will return the same
subtype of 'Node'.
For your purposes you have determined that it is only necessary to claim that
the 'List' contains 'Node', ergo you don't need to use 'extends Node' in your
type parameter.
--
Lew