2012-01-06 105 views
4

因为我一直没有使用泛型,在这个例子中我很困惑。在java中使用泛型时出现空指针异常

我有以下的抽象基类:

public abstract class ExcelReader<T>{ 
    protected T type; 
    protected GenericResolver resolver; 

    public ExcelReader(){ 
     super(); 
     resolver=ResolverFactory.createResolver(type.getClass()); 
    } 
} 

现在我的子类如下:

public class POIReader<T> extends ExcelReader<T>{ 

} 
//...Implementation of methods ommited for brevity 

现在在我的服务,我通过以下方式创建新的对象:

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

但是,当调用ExcelReader构造函数时,type属性为null,而在cons在创建解析器时会引发NullPointer异常。

我想你可以得到我想要做的与上面的代码片段的想法,我已经看到使用属性字段来保存参数化类类型的例子。

但是我很困惑,为什么我在类型属性中得到空值,我怎么能避免它。 非常感谢。

回答

0

我不认为你要使用仿制药的事他们打算使用。泛型是一种“语法糖”,在编译时仅可使用作为附加级别的代码验证。你似乎想要达到的目的 - 如果我错了 - 纠正我的错误 - 就是将泛型类型提供给POIReader类,然后(在运行时)能够访问此类型的类对象。它是否正确?

的方式,你可以使用你的榜样仿制药 - 但我不知道这将是你想达到什么 - 是这样的:

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); 
    } 
} 

然后:

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

这样,由于使用泛型,编译器将不允许将任何不可分配给MessageDTO类的任何内容作为参数传递给POIReader的构造函数 - 但您仍必须将分配给到该值字段以便能够调用getClass()方法。这是因为,由于类型擦除的泛型(一个不幸的向后兼容的东西),您提供的泛型是而不是在运行时可用,仅在编译时。

13

你叫type.getClass(),但在那一点type保证为空。没有其他的代码有机会设置它,所以你如何期待它的工作?你说你对它为什么是空的感到困惑 - 但你没有显示任何使它非空的东西。

我怀疑你想要的东西,如:

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); 
    } 
} 

你想要引进的同类型参数的子类了。

0

你确切地解释了这个问题。 type为空。那么,你需要做什么?使它不为空。修改构造函数如下:

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

现在,您的子类必须发送此参数,例如,

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

或者你可以让你的子类的通用了,所以在发送类型的责任转移到客户端:

public class POIReader<T> extends ExcelReader<T>{ 
    public POIReader(Class<T> type) { 
     super(type); 
    } 
} 

// and call it: 
new POIReader(MessageDTO.class); 
相关问题