简体   繁体   中英

How to deliver the class of a generic type to a method in Java?

I want to implement a class that instantiates generic types.

public class DisjointSet<T extends Set<E>, E> {

    private final Class<T> setType;

    public DisjointSet(Class<T> setClass) {
        this.setType = setClass;
    }

    public void doSomething(E Element) {
        T set = setClass.newInstance();
        set.add(element);
    }
}

I tried instantiating the class like this:

DisjointSet<HashSet<Integer>, Integer> disjointSet = new DisjointSet<>(HashSet<Integer>.class);

However using .class on a generic type does not seem to be allowed. How would I correctly pass the required Class of a generic type to the constructor?

Not sure it is good to expose the inner set type (Hash versus other) in the parameterized type. Actually due to type erasure you can't instantiate parameterised types directly, but you can pass in a factory,

package langGenerics;

import java.util.HashSet;
import java.util.Set;

public class UseGenerics {
  public static void main(String[] args) {
    SetFactory<Integer> setFactory = HashSet::new;
    DisjointSet<Integer> disjointSet = new DisjointSet<>(setFactory);
    disjointSet.doSomething( 123 );
  }
}

interface SetFactory<T> { Set<T> get(); }

class DisjointSet<T> {
  private SetFactory<T> setFactory;
  public DisjointSet(SetFactory<T> setFactory) {
    this.setFactory = setFactory;
  }
  public void doSomething(T item) {
      Set<T> set = setFactory.get();
      set.add(item);
  }
}

If you really want to init your own set storage, then I suggest you to pass Supplier to your constructor:

public static class DisjointSet<T extends Set<E>, E> {
    T set;
    public DisjointSet(Supplier<T> supplier) {
        set = supplier.get();
    }

    public void doSomething(E element) {
        set.add(element);
    }
}

Then use it:

DisjointSet<HashSet<Integer>, Integer> set = new DisjointSet<>(HashSet::new);

if this is what you wanted,

public class DisjointSet<T extends Set<E>, E> {

    private final Class<T> setType;

    public DisjointSet(Class<T> setClass) {
        this.setType = setClass;
    }

    public static void main(String[] args) {
        DisjointSet<HashSet<Integer>, Integer> disjointSet = new DisjointSet(new HashSet<Integer>().getClass());
    }
}

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