我正在尝试将以下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();
}
因此,请帮助我实例化通用对象数据的正确语法
答案 0 :(得分:2)
您无法实例化泛型。原因是类型在运行时不可用,但实际上由编译器替换为Object
。所以
T data = new T(); // Not valid in Java for a generics T!
实际上是:
Object data = new Object(); // Obviously not the desired result
阅读Java Generics Tutorial wrt。至于“type erasure”了解详情。
您需要使用factory pattern。
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
时为实际的最终类型实现它。
答案 1 :(得分:1)
运气好;在Java中,整个泛型完全是一个编译时工件,类型参数的实例化并不存在于运行时中。通常的解决方法是将Class
的实例作为标记传递,这将允许您反射性地创建该类型的对象。这充满了许多陷阱,但这是Java中最好的。
答案 2 :(得分: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具有无参数构造函数。