[英]java generics issue
im new to generics concept in java 我是java中的泛型概念的新手
In my application im using generics in one class, following is the my sample code 在我的应用程序中,我在一个类中使用泛型,以下是我的示例代码
public class GPBFormat<T extends Message> implements IGPBFormat<T> {
@Override
public byte[] serialize(T t)
{
return t.toByteArray();
}
@Override
public T deSerialize(byte[] value)
{
T.parseFrom(value);
return null;
}
im above code im using parseFrom
method, but the problem is this method will exist only in concrete classes ie which classes extends the Message
class, so im unable to access parseFrom
method with this generics. 我上面的代码我使用
parseFrom
方法,但问题是这个方法只存在于具体的类中,即哪些类扩展了Message
类,所以我无法使用这个泛型访问parseFrom
方法。 How can i solve this? 我怎么解决这个问题?
Thanks, R.Ramesh 谢谢,R.Ramesh
Pass in to the constructor(s) a factory object, along the lines of: 将构造函数传递给工厂对象,类似于:
interface Parser<T extends Message> {
T parseFrom(byte[] value);
}
If GPBFormat
does little more than you've quoted, then perhaps it should be abstract and not delegate to a separate factory. 如果
GPBFormat
所做的只比你引用的要多,那么也许它应该是抽象的而不是委托给一个单独的工厂。
You can declare an abstract parseFrom
method in your Message
class. 您可以在
Message
类中声明一个抽象的parseFrom
方法。 Concrete classes will then be required to implement it, which is exactly what you need for the above code to work properly. 然后需要具体的类来实现它,这正是您需要上面的代码才能正常工作。
Based on the comment by Tom Hawtin, here's a modified version of my answer: 基于Tom Hawtin的评论,这是我的答案的修改版本:
public class GPBFormat<T extends Message> implements IGPBFormat<T> {
private Class<T> clazz;
public GPBFormat(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) {
return t.toByteArray();
}
@Override
public T deSerialize(byte[] value)
{
try {
T thing = clazz.newInstance();
thing.parseFrom(value);
return thing;
} catch (Exception e) {
// report error
return null;
}
}
}
Each concrete class will need a no-arg constructor. 每个具体类都需要一个no-arg构造函数。
Are these protocol buffers? 这些协议缓冲区? Is your
parseFrom
method static? 你的
parseFrom
方法是静态的吗?
If parseFrom
is not static, you should do 如果
parseFrom
不是静态的,你应该这样做
@Override
public boolean deSerialize(T message, byte[] value)
{
// protocol messages return boolean whether parsing succeeded
return message.newBuilderForType().mergeFrom(value).build();
}
Often it is not enough to just pass type variable (T), but also Class; 通常仅仅传递类型变量(T),还有Class; for example, deserialize usually should be something like:
例如,反序列化通常应该是这样的:
public T deSerialize(byte[] value, Class<T> type)
because T in this case is mostly just used by compiler to generate implicit casts. 因为在这种情况下T大多只是由编译器用来生成隐式转换。 So you still need actual class to be passed -- this is one common Java idiom, needed due to type erasure.
所以你仍然需要传递实际的类 - 这是一种常见的Java习语,由于类型擦除而需要。
you need a generic Parser : 你需要一个通用的Parser:
@Override
public T deSerialize(byte[] value, Parser<T> parser)
{
return parser.parseFrom(value);
}
client code : 客户代码:
ConcreteMessage msg = deSerialize(byteArray, ConcreteMessage.getParserForType());
You can access the parseFrom() method in this way only if it is static. 只有在静态的情况下,才能以这种方式访问parseFrom()方法。 If you make that method static then this code will work.
如果您将该方法设为静态,那么此代码将起作用。 If you don't want to make that static then use instance to call it that is an instance method can be called only through an instance.
如果你不想使那个静态然后使用实例来调用它,那么实例方法只能通过实例调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.