2014-02-24 123 views
2

我有下面的類層次結構,它只是實現了編碼和解碼來自給定字節數組的動物的想象功能。在泛型中的類型安全

public abstract class Animal { 
} 

class Tiger extends Animal{ 
    private String name; 

    public void setName() { 
    } 

    public String getName() { 
     return this.name; 
    } 
} 

abstract class AnimalTransformer { 
    public static <T> T decodeAnimalFromBytes(byte[] animalInBytes) { 
     return null; 
    } 

    public static byte[] encodeAnimalInBytes(Animal animal) { 
     return null; 
    } 

}

class TigerTransformer extends AnimalTransformer{ 
    public static Tiger decodeAnimalFromBytes(byte[] animalInBytes) { 
     return new Tiger(); 
    } 

    public static byte[] encodeAnimalinBytes(Tiger tiger) { 
     return new byte[0]; 
    } 
} 

在從AnimalTransformer抽象類中延伸AnimalTransformer的TigerTransformer類覆蓋的方法,我得到以下警告

Type safety: The return type Tiger for decodeAnimalFromBytes(byte[]) from the type 
TigerTransformer needs unchecked conversion to conform to T 
from the type AnimalTransformer 

我明白這個警告的原因但不幸的是我不能解決它,因爲我是泛型的新手。有人可以簡要解釋如何解決這個警告?

回答

1

首先,不要試圖用靜態方法「覆蓋」。它不會像你認爲的那樣工作 - 「覆蓋」的靜態方法仍然可以通過偏僻(偶然)的方式從子類訪問。如果您想重寫行爲,請使用本地方法。

警告正在產生,因爲Tiger方法簽名與超級方法承諾不兼容 - 客戶端選擇的任何類<T>可以解碼爲,這是一個非常大的,無法實現的承諾。

一個更好的方法是:

abstract class AnimalTransformer<T extends Animal> { 
    public T decodeAnimalFromBytes(byte[] animalInBytes) { 
    return null; 
    } 
    public static byte[] encodeAnimalInBytes(T animal) { 
    return null; 
    } 
} 

class TigerTransformer extends AnimalTransformer<Tiger> { 
    public Tiger decodeAnimalFromBytes(byte[] animalInBytes) { 
    return new Tiger(); 
    } 
    public byte[] encodeAnimalinBytes(Tiger tiger) { 
     return new byte[0]; 
    } 
} 

這代表你想更清楚地進行建模的東西 - 一個AnimalTransformer提供的Animal一些子類轉化方法,它是由子類,或匿名的實現,澄清哪些。

+0

但我只需要以靜態方式訪問功能,即通過不實例化TigerTransformer,我想像TigerTransformer.encodeToBytes()那樣訪問它,因爲實例化這種類不合邏輯。不能以靜態方式訪問? –

+0

它不合邏輯嗎?如果您需要,如果您擔心多個實例,則可以將TigerTransformer作爲單例提供。 (或者,更好的是,提供所有變壓器的AnimalTransformers類)。如果你真的不想實例化它,那麼使用繼承和遺傳是沒有意義的 - 你可以選擇其中一個。 – torquestomp

+0

謝謝..我的意思是這個類只是提供了編碼和解碼的功能,所以用它們的類名稱來調用它們,比如聲明靜態,我認爲它比實例化更好。並且使用單例設計模式這些課程對我來說很好,所以我會一起去。 –

2

請注意,使AnimalTransformer的方法靜態是沒有用的。靜態方法不會通過繼承來相互覆蓋。此外,您不綁定變換器處理解碼對象類型的數據類型(例如,TigerTransformer可以返回Horse對象)。

我會做,而不是下面的,我認爲是更安全的類型:

所有的
abstract class AnimalTransformer <T> { 
    public abstract T decodeAnimalFromBytes(byte[] animalInBytes); 

    public abstract byte[] encodeAnimalInBytes(T animal); 
}