3

次のC#コードをJavaに変換しようとしています

abstract class BaseProcessor<T> where T : new()
{
 public T Process(HtmlDocument html)
 {
         T data = new T();

        Type type = data.GetType();
        BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty;
        PropertyInfo[] properties = type.GetProperties(flags);
        foreach (PropertyInfo property in properties)
        {
             string value = "test";
             type.InvokeMember(property.Name, flags, Type.DefaultBinder, data, new object[] { value });
        }
 }
}

だから私はまでやった

public class BaseProcessor<T> 
{
   public T Process(String m_doc)
   {
      T data = (T) new BaseProcessor<T>(); // this is not working

      Document doc = Jsoup.parse(m_doc);
      return data;
   }
}

データオブジェクトをインスタンス化すると、実行時にGenericクラスのプロパティを取得しません。たとえば、コードをヒットしたときに、DecodeModelクラスのプロパティを取得しません。

IDocProcessor<DecodeModel> p = new DecodeThisProcessor();
return p.Process(doc);


public interface IDocProcessor<T>
{
    T Process(String webresponse);
}

public class DecodeThisProcessor extends BaseProcessor<DecodeModel> implements IDocProcessor<DecodeModel>
{
public void setup();
}

したがって、ジェネリックオブジェクトデータをインスタンス化するための正しい構文を教えてください

4

3 に答える 3

2

ジェネリックをインスタンス化することはできません。その理由は、この型は実行時に使用できませんが、実際にObjectはコンパイラによって置き換えられるためです。それで

T data = new T(); // Not valid in Java for a generics T!

実際には次のようになります。

Object data = new Object(); // Obviously not the desired result

JavaGenericsチュートリアルを読んでください。詳細については、「型消去」を参照してください。


ファクトリパターンを使用する必要があります。

T data = factory.make();

どこ

public interface Factory<T> {
     T make();
}

実装してコンストラクターに渡す必要があります。これを機能させるには、目的のクラスをインスタンス化する方法を知っているファクトリが必要です。

(かなり明白な)変形は、ファクトリメソッドを--abstract--クラスに入れることです。

public abstract class BaseProcessor<T> 
{
   protected abstract T makeProcessor();

   public T Process(String m_doc)
   {
       T data = makeProcessor(); // this is now working!

拡張するときBaseProcessorは、実際の最終タイプに実装します。

于 2012-12-27T12:23:18.020 に答える
1

頑張ってください。Javaでは、ジェネリックス全体が厳密にコンパイル時のアーティファクトであり、型パラメーターのインスタンス化はランタイムに存在しません。通常の回避策は、インスタンスをClassマーカーとして渡すことです。これにより、そのタイプのオブジェクトを反射的に作成できます。これには多くの落とし穴がありますが、Javaで得られる最高のものです。

于 2012-12-27T12:14:00.523 に答える
0

あなたはこれを行うことができます:

public class BaseProcessor<T>
{
    private Class<T> clazz;

    public BaseProcessor(Class<T> clazz)
    {
        this.clazz = clazz;
    }

    public T Process(String m_doc)
    {
         T data = clazz.newInstance()
         Document doc = Jsoup.parse(m_doc);
         return data;
    }
}

ヒント:Tに引数なしのコンストラクターがあることを確認してください。

于 2012-12-27T12:10:50.200 に答える