简体   繁体   中英

Java - How to get concrete parameter type when overriding interface method of generic type

I am a generics newbie and I am not able to find out the best way to achieve this. Please feel free to point out if I am doing something obviously wrong.

interface Node<T> {

    void addOne(Node<T> node);
}

class StringNode implements Node<String> {

    List<StringNode> data = new ArrayList<>();

    /**
     * {@inheritDoc}
     */
    @Override
    public void addOne(Node<String> node) {
        StringNode stringNode = (StringNode) node;
        data.add(stringNode);
    }

}

I was hoping to find a way to avoid the downcast from Node to StringNode in the implementation of addOne by having the function itself be of signature public void addOne(StringNode node) . Any ideas as to how the definition of Node can be changed to achieve this for any implementation of the interface?

I tried searching through the questions already asked, but was not able to find a close match. Any pointers to questions where this has already been discussed would also be greatly appreciated.

Thanks in advance!

Why are you using String and StringNode separatly? Couldn't you just say

interface Node<T> {

    void addOne(T node);
}

class StringNode implements Node<StringNode> {

    List<StringNode> data = new ArrayList<StringNode>();

    /**
     * {@inheritDoc}
     */
    @Override
    public void addOne(StringNode node) {
        StringNode stringNode =  node;
        data.add(stringNode);
    }

}

This is how I would have done it:

interface Node<T extends Node<T>> {

    void addOne(T node);
}

class StringNode implements Node<StringNode> {

    List<StringNode> data = new ArrayList<StringNode>();

    /**
     * {@inheritDoc}
     */
    @Override
    public void addOne(StringNode node) {
        data.add(node);
    }

}

Similar to U-No-Poo's suggestion, but a little more strict (forces T to actually be a node)

You could introduce another generic parameter:

public interface Node<VALUE_TYPE, SELF> {
  public void addOne(SELF u);
}

public class StringNode implements Node<String, StringNode> {

  @Override
  public void addOne(StringNode u) {
    // TODO Auto-generated method stub  
  }
}

Use VALUE_TYPE whenever you need the actual value type (in this case String) and SELF whenever you want to pass a node of that type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM