2011-02-16 93 views
4

即时通讯新在JavaJava泛型问题

在使用泛型在一个类中我的应用程序IM仿制药的概念,下面是用parseFrom方法我的示例代码

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上面的代码即时通讯,但问题是这种方法将只存在于具体类中,即哪些类扩展了Message类,所以我无法访问此泛型的parseFrom方法。我该如何解决这个问题?

感谢, R.Ramesh

+0

您可以发布parseFrom方法定义? – Necronet 2011-02-16 06:02:46

回答

2

这些协议缓冲区?您的parseFrom方法是否是静态的?

如果parseFrom也不是一成不变的,你应该做

@Override 
public boolean deSerialize(T message, byte[] value) 
{ 
    // protocol messages return boolean whether parsing succeeded 
    return message.newBuilderForType().mergeFrom(value).build(); 
} 
2

您可以在Message类中声明的抽象方法parseFrom。然后需要具体的类来实现它,这正是上述代码正常工作所需的。

根据汤姆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; 
     } 
    } 
} 

每个具体类都需要一个无参数的构造函数。

+1

我不这么认为。没有实例可以调用该方法。 – 2011-02-16 06:09:44

+0

糟糕。我没有注意到OP正试图对方法进行静态引用。 – 2011-02-16 20:17:17

3

传递到构造函数(S)工厂对象,沿着线:

interface Parser<T extends Message> { 
    T parseFrom(byte[] value); 
} 

如果GPBFormat做多一点你已经引用过,那么也许它应该是抽象的,而不是委托给一个单独的工厂。

0

只有在静态的情况下,您才能以这种方式访问​​parseFrom()方法。如果你使这个方法是静态的,那么这个代码将会工作。如果你不想让这个静态的,那么使用实例来调用它,即实例方法只能通过一个实例调用。

1

通常仅仅传递类型变量(T)是不够的,但也是Class;例如,反序列化通常应该是这样的:因为T IN这种情况下,大多只是使用编译器生成隐式转换

public T deSerialize(byte[] value, Class<T> type) 

。所以你仍然需要传递实际的类 - 这是一种常见的Java成语,由于类型擦除而需要。

0

你需要一个通用的解析器:

@Override 
public T deSerialize(byte[] value, Parser<T> parser) 
{ 
    return parser.parseFrom(value); 
} 

客户端代码:

ConcreteMessage msg = deSerialize(byteArray, ConcreteMessage.getParserForType());