Java generics issue

im a new concept of generics in java

In my im application using generics in one class, the following is 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 over im code using the parseFrom method, but the problem is that this method will exist only in specific classes. Which classes extend the Message class, so they cannot access the parseFrom method with these generics. How can i solve this?

Thanks R.Ramesh

+4
source share
6 answers

Are these protocol buffers? Is your parseFrom method static?

If parseFrom not static, you should do

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

Go to the constructor (objects) of a factory object line by line:

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

If GPBFormat does a little more than what you quoted, perhaps it should be abstract and not pass to a separate factory.

+3
source

You can declare an abstract parseFrom method in the Message class. Then concrete classes will be required to implement it, which is exactly what you need for the above code to function properly.

Based on Tom Khotin's comment, the version of my answer was modified here:

 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.

+2
source

It is often not enough to simply pass a variable of type (T), but also a class; for example, deserialization should usually look something like this:

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

because T in this case is mainly used by the compiler to generate implicit jobs. So you still need the actual class you need to pass in - this is one common Java idiom needed due to type erasure.

+1
source

You can access the parseFrom () method this way only if it is static. If you make this method static, this code will work. If you do not want to make this static, use an instance to call it, which is an instance method that can only be called through an instance.

0
source

you need a common parser:

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

client code:

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

Source: https://habr.com/ru/post/1339943/


All Articles