2012-01-06 204 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);