Null pointer exception when working with generics in java

since I have not used generics for some time, I'm rather confused in this example.

I have the following base abstract class:

public abstract class ExcelReader<T>{ protected T type; protected GenericResolver resolver; public ExcelReader(){ super(); resolver=ResolverFactory.createResolver(type.getClass()); } } 

now my subclass is as follows:

 public class POIReader<T> extends ExcelReader<T>{ } //...Implementation of methods ommited for brevity 

Now in my service, I create a new object as follows:

 ExcelReader<MessageDTO> reader=new POIReader<MessageDTO>(); 

However, when the ExcelReader constructor is called with the type attribute, it is null and throws a NullPointer exception in consecuence when creating the recognizer.

I think you can understand what I'm trying to do with the code snippets above, and I saw examples using the attribute field to save the type of the parameterized class.

However, I am completely confused by why I get null in the type attribute, and how I could avoid it. Thank you very much.

+4
source share
3 answers

I do not think that you are trying to use generics for what they want to use. Generics are a kind of โ€œsyntactic sugarโ€ that can only be used at compile time as an additional level of code verification. What you want to achieve โ€” correct me if I am mistaken โ€” to provide a generic type to your POIReader class, and then be able (at runtime) to access that class class. Is it correct?

How you could use generics in your example - but I'm not sure if this will be what you want to achieve - here is something like this:

 public abstract class ExcelReader<T>{ protected T value; protected GenericResolver resolver; public ExcelReader(T value) { super(); resolver=ResolverFactory.createResolver(type.getClass()); } } public class POIReader<T> extends ExcelReader<T>{ public POIReader(T value) { super(value); } } 

and then:

 MessageDTO yourObject = ...; ExcelReader<MessageDTO> reader=new POIReader<MessageDTO>(yourObject); 

Thus, due to the use of generics, the compiler will not allow you to pass everything that is not assigned to the MessageDTO class as an argument to the POIReader constructor, but you still need to assign something to this value field in order to be able to call the getClass() method. This is due to the fact that due to the deletion of generic types (unsuccessful backward compatibility), the generics you generate are not available at run time, only at compile time.

0
source

You call type.getClass() , but at this point type guaranteed to be null. No other code would be able to install it, since you expected it to work? You say that you are embarrassed by why it is empty, but you have not shown anything that would make it non-zero.

I suspect you want something like:

 public abstract class ExcelReader<T>{ protected final Class<T> type; protected GenericResolver resolver; public ExcelReader(Class<T> type){ this.type = type; resolver = ResolverFactory.createResolver(type); } } 

You must also enter the same parameter in subclasses.

+13
source

You accurately explained the problem. The value of type is null. So what do you need to do? Make it non-empty. Modify the constructor as follows:

  protected ExcelReader(T type){ super(); this.type = type; resolver=ResolverFactory.createResolver(type.getClass()); } 

Now your subclass should send this parameter, for example.

 public class POIReader extends ExcelReader<MessageDTO>{ public POIReader() { super(MessageDTO.class); } } 

Alternatively, you can also create your own subclass, so that the responsibility for sending the type is transferred to the client:

 public class POIReader<T> extends ExcelReader<T>{ public POIReader(Class<T> type) { super(type); } } // and call it: new POIReader(MessageDTO.class); 
0
source

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


All Articles