2011-02-16 91 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());