2013-03-07 189 views
3

我有以下代碼:的Java類型轉換,從擴展

public static <T extends User> void addUser(String username, 
     String passwordHash, Class<T> userClass, File usersDir) { 

    T user = (T) new User(username, passwordHash); 
    UserManager.toFile(user, usersDir); 
} 

Eclipse中給了我以下警告:

Type safety: Unchecked cast from User to T

爲什麼我得到警告,它不是檢查,如果我定義T將用戶擴展爲<T extends User>

+0

因爲不管你是否使用泛型,你都不能低調嗎?除非'T' *是*'User',否則它是無效的。 – 2013-03-07 17:06:12

回答

7

您誤解了泛型。

T extends User並不意味着TUser;這意味着T可以是任何繼承User的類。

如果TFunkyUser,那麼您的代碼將不起作用。

+0

我現在正在使用這個:'T user2 = userClass.cast(new BaseUser(username,passwordHash));'。這是否更好? (順便說一句,我會在5分鐘內接受你的回答,當noob保護允許我¬¬) – Twinone 2013-03-07 17:14:33

+0

有了這些代碼,我不再收到警告。有什麼不同? – Twinone 2013-03-07 17:16:15

+0

@TwinOneAndroid - 你沒有得到警告,因爲它會檢查轉換,並且如果你傳遞除User.class之外的任何東西,將會拋出一個異常......這又回到'T擴展用戶',因爲你可以'這樣做。你的原始方式不會炸燬,直到你真的試圖使用'user' – 2013-03-07 17:24:32

2

T可以是任何擴展類User。你正在實例化一個新的User,即超類。因此,如果T不是剛好User類型(即一個子類),演員陣容是不安全的,並將投擲ClassCastException

+0

這個演員不是非法的,因爲它的*不安全*。 – Perception 2013-03-07 17:08:10

+0

@Perception恕我直言,它不是一種安全/不安全的東西,因爲'T類是'一個子類時拋出'ClassCastException',我錯了嗎? – sp00m 2013-03-07 17:09:25

+0

在這種情況下,*非法*轉換是編譯器會捕獲的,而* unsafe *可能會導致運行時異常(在本例中是'ClassCastException')。 – Perception 2013-03-07 17:11:35

0

最低T可以是一個用戶,實際上它也可以AdvancedUser

class AdvancedUser extends User{} 

然後如果你聲明T作爲一種先進的用戶,因爲你向上轉型真正的用戶對象AdvancedUser類型的程序將失敗。因此,它給你一個關於不安全的轉換的警告