Search code examples
javagenericshtmlunit

How does generic type in declaration really affects the method if it's never used?


I'm looking through HTMLUnit sources and can't quite figure out how is generic type supposed to work here. It's never used inside the method, what's the point of making the method generic?

public <T> List<T> getByXPath(final String xpathExpr) {
        PrefixResolver prefixResolver = null;
        if (hasFeature(XPATH_SELECTION_NAMESPACES)) {
            /*
             * See if the document has the SelectionNamespaces property defined.  If so, then
             * create a PrefixResolver that resolves the defined namespaces.
             */
            final Document doc = getOwnerDocument();
            if (doc instanceof XmlPage) {
                final ScriptableObject scriptable = ((XmlPage) doc).getScriptableObject();
                if (ScriptableObject.hasProperty(scriptable, "getProperty")) {
                    final Object selectionNS =
                            ScriptableObject.callMethod(scriptable, "getProperty", new Object[]{"SelectionNamespaces"});
                    if (selectionNS != null && !selectionNS.toString().isEmpty()) {
                        final Map<String, String> namespaces = parseSelectionNamespaces(selectionNS.toString());
                        if (namespaces != null) {
                            prefixResolver = new PrefixResolver() {
                                @Override
                                public String getBaseIdentifier() {
                                    return namespaces.get("");
                                }

                                @Override
                                public String getNamespaceForPrefix(final String prefix) {
                                    return namespaces.get(prefix);
                                }

                                @Override
                                public String getNamespaceForPrefix(final String prefix, final Node node) {
                                    throw new UnsupportedOperationException();
                                }

                                @Override
                                public boolean handlesNullPrefixes() {
                                    return false;
                                }
                            };
                        }
                    }
                }
            }
        }
        return XPathUtils.getByXPath(this, xpathExpr, prefixResolver);
    }

Solution

  • The generics here are used to infer the type T into the XPathUtils.getByXPath method, which signature is

    public static <T> List<T> getByXPath(DomNode node, String xpathExpr, PrefixResolver resolver)
    

    When compiler looks at this statement

    return XPathUtils.getByXPath(this, xpathExpr, prefixResolver);
    

    it infers the T type from the outer getByXPath method, which in turn infers T from its invocation.

    So if you call List<HtmlDivision> list = page.getByXPath(expr); then HtmlDivision will be inferred into getByXPath and then into XPathUtils.getByXPath