简体   繁体   English

java泛型问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM