[jdom-interest] JDom and Java5

Rolf jdom at tuis.net
Sat Feb 23 06:51:53 PST 2008


Hi Gregor

Hmm... actually, I somewhat disagree (in this particular circumstance). 
I have been thinking about this a bit more

Here's the 'current' code behind the method (after I modified it 
yesterday)...

   public List<?> selectNodes(Object context) throws JDOMException {
      try {
         currentContext = context;
         return xPath.selectNodes(context);
      } catch (JaxenException ex1) {
         throw new JDOMException("XPath error while evaluating \"" + 
xPath.toString() + "\": " + ex1.getMessage(), ex1);
      } finally {
         currentContext = null;
      }
   }

Here's the signature on the xPath method that is supplied by Jaxen:

List <http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html> 
*selectNodes*(Object 
<http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> context) 
throws JaxenException 
<http://jaxen.codehaus.org/apidocs/org/jaxen/JaxenException.html>

Given that XPath can return all sorts of values (not all of them are JDom Content (like Attribute which is not Content)), then we have a real problem with this method.

There is no way I can see (even by modifying Jaxen) to return a list of any specific type other than Object. It would be real nice if an xpath that returned just Elements would have a return type of List<Element>, but that just isn't feasible.

The next best thing is to return something appropriate, and that should be the same as what Jaxen would return if it were Generified.

Thus, the best thing would be to consider things from Jaxen's POV, and let the 'client' sort it out.

Since Jaxen does not know anything about the actual content in the 'context' (it is all delegated to a JDom specific implementation), and that implementation has to be able to return both Attribute and Content, the best that Jaxen could do is return List<Object>.

The Jaxen code would have no option but to look something like:

List<Object> ret = new XXXList<Object>();
for (..... nodes in context ...) {
  if (... node matches the xpath ...) {
     ret.add(node);
  }
}


because it will potentially have to add Attributes, Elements, Text, etc. (and that's just for JDom, for other API's it will need other constructs).

As a consequence, the Jaxen code, if it were Generified, would have no option but to return List<Object> from the method, just like it returns Object from the method selectSingleNode();

Object <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> *selectSingleNode*(Object <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> context) throws JaxenException <http://jaxen.codehaus.org/apidocs/org/jaxen/JaxenException.html>

In other words, I have come back around the circle and I believe that 
the method should return exactly List<Object> rather than List<?> or 
List<? extends Object>.

As further considerations against the alternatives:

returning List<? extends Object> implies that the actual returned list 
may be any other specific type as well, e.g. List<String> or 
List<Element> or even something silly like List<System>. This will not 
be the case, the actual returned type will in fact be List<Object> and 
there is no point in making it more obscure by saying List<? extends 
Object> because that actually reduces the meaning.

returning List<?> implies that we have no idea what's in the list, but 
we do.

The logical answer appears to be returning List<Object>. This makes the 
most sense until Jaxen finds a way for the method 
returnSingleNode(Context) to return a type other than Object. Here's the 
Jaxen code:

    public Object selectSingleNode(Object node) throws JaxenException {
        List results = selectNodes( node );
        if ( results.isEmpty() ) {
            return null;
        }
        return results.get( 0 );
    }

If Jaxen can be generified to have something like:

    public T <T extends Object> selectSingleNode(Object node) throws 
JaxenException {
        List<T> results = selectNodes( node );
        if ( results.isEmpty() ) {
            return null;
        }
        return results.get( 0 );
    }

only then should we consider the alternatives....

On the other hand, the client-side code calling the XPath method is 
going to have to jump through all sorts of instanceof hoops anyways, and 
the return type does not really affect that in any way.

As for Mattias's original claim that List<?> can be cast to 
List<Element> if you know the content will be only Elements, then, I 
believe that lends a certain weight to List<?>, but, is the same not 
true for List<Object>? At some point you will have a compile-time 
warning about unchecked types... unless you do individual casts to 
Element on the contents of the List anyway.

Does this make sense? This whole topic is somewhat interesting, and I do 
see the value in different implementations. There appears to be more 
than one right answer, all with different compromises. At the moment I 
am more in the List<Object> camp but am willing to be convinced 
otherwise....

Rolf

Gregor Zeitlinger wrote:
> I think List<? extends Object> is more appropriate.
>
> It shows that the code has been generified (as opposed to using a plain List).
> It's similiar to List<?>, but shows that Object is indeed the least
> common denomiator.
> _______________________________________________
> To control your jdom-interest membership:
> http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com
>
>   



More information about the jdom-interest mailing list