Javaで汎用クラスをインスタンス化する


Answers

これはJon Skeetが提案したように、Factory実装です。

interface Factory<T> {
    T factory();
}

class Araba {
    //static inner class for Factory<T> implementation
    public static class ArabaFactory implements Factory<Araba> {
        public Araba factory() {
            return new Araba();
        }
    }
    public String toString() { return "Abubeee"; }
}

class Generic<T> {
    private T var;

    Generic(Factory<T> fact) {
        System.out.println("Constructor with Factory<T> parameter");
        var = fact.factory();
    }
    Generic(T var) {
        System.out.println("Constructor with T parameter");
        this.var = var;
    }
    T get() { return var; }
}

public class Main {
    public static void main(String[] string) {
        Generic<Araba> gen = new Generic<Araba>(new Araba.ArabaFactory());
        System.out.print(gen.get());
    }
}

出力:

Constructor with Factory<T> parameter
Abubeee
Question

私は、Javaのジェネリックスが.NETのやや劣っていることを知っています。

私はジェネリッククラスFoo<T>を持っていFoo<T> 、そして、私は実際には、パラメータなしのコンストラクタを使ってFoo Tをインスタンス化する必要があります。 どのようにしてJavaの制限を回避できますか?




https://.com/a/2434094/848072から。 Tクラスのデフォルトコンストラクタが必要です。


import java.lang.reflect.ParameterizedType;

class Foo {

  public bar() {
    ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
    Class type = (Class) superClass.getActualTypeArguments()[0];
    try {
      T t = type.newInstance();
      //Do whatever with t
    } catch (Exception e) {
      // Oops, no default constructor
      throw new RuntimeException(e);
    } 
  }
}




私は実際には、パラメータのないコンストラクタを使ってFooでTをインスタンス化する必要があります

単純な答えは "あなたはそれを行うことはできません" javaは、これを行うのを妨げるジェネリックを含めるために型の消去を使用します。

どのようにしてJavaの制限を回避できますか?

1つの方法(他にもあり得る)は、Tのインスタンスを渡すオブジェクトをFoo<T>コンストラクタに渡すことです。 あるいは、メソッドsetBar(T theInstanceofT);持つことができsetBar(T theInstanceofT); クラスでインスタンス化する代わりにTを取得する




Java 8の場合....

https://.com/a/36315051/2648077投稿には良い解決策がありhttps://.com/a/36315051/2648077 。

これは、Java 8 Supplier機能インタフェース