简体   繁体   中英

One interface for different generic classes

I am having a bit trouble with generics in Java because I am not sure if what I am trying to achieve actually exists.

I wrote the following class (simplified here, without getter/setter):

public class Pair<T>{
  public T firstEntry;
  public T secondEntry;

  public Pair(T p_First, T p_Second) {
      this.m_First = p_First;
      this.m_Second = p_Second;
  }
}

Now I want actually the same class but with the possibility that firstEntry and secondEntry can be of different type. For example some class like this:

public class PairMultipleType<T, K>{
  public T firstEntry;
  public K secondEntry;

  public Pair(T p_First, K p_Second) {
      this.m_First = p_First;
      this.m_Second = p_Second;
  }
}

But I want to use the classes like this:

Pair<Integer> myPair = new Pair<Integer>(a, b); //Creates pair with one type.
Pair<Integer, String> myPair = new Pair<Integer, String>(a, "Hallo Welt"); //Creates pair with two types.

I am aware that this code would be wrong anyways because the classes may not have the same name. But that is the point: Is it possible to write an interface to which I can use to achieve the desired behaviour? If it is possible, how can it be done?

What you're trying to do is not allowed due to type erasure . The suggestion made in the comments is a good alternative: have a Pair<T,K> base class and have an extending SingleTypePair<T> class.

class Pair<T, K> {
    protected T firstEntry;
    protected K secondEntry;

    public Pair(T firstEntry, K secondEntry) {
        this.firstEntry = firstEntry;
        this.secondEntry = secondEntry;
    }
}

class SingleTypePair<T> extends Pair<T, T> {

    public SingleTypePair(T firstEntry, T secondEntry) {
        super(firstEntry, secondEntry);
    }
}

You can't declare your Pair variables (or the class itself) to have a variable number of type parameters.

But what you could do is have Pair extend PairMultipleType , but define its only type parameter to be both parameters of PairMultipleType .

public class Pair<T> extends PairMultipleType<T, T> {
    public Pair(T p_First, T p_Second) {
        super(p_First, p_Second);
    }
}

Be careful with this design, because it's easy to mix up your generic type parameters. But you can do this:

Pair<String> pair = new Pair<String>("one", "two");
PairMultipleType<String, String> pair2 = new Pair<String>("one", "two");
PairMultipleType<Integer, String> pair3 = new PairMultipleType<Integer, String>(1, "one");

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