2010-01-27 49 views
2

例如,我使用方法Measure.doubleValue(Unit<?> unit),它返回測量值double,用指定的Unit表示。如果我通過一個Unit<?>變量它,我得到的還是很神祕的(對我)的錯誤信息:爲什麼我不能在接收參數化參數的方法中使用通配符?

The method doubleValue(Unit<capture#27-of ?>) in the type Measurable<capture#27-of ?> is not applicable for the arguments (Unit<capture#28-of ?>)

我將不勝感激,如果有人可以解釋什麼是#27-of ?(或任何其他數)的意思,如果有一個優雅的方式來擺脫這一點。到目前爲止,我刪除<?>,並設置呼叫方法@SuppressWarnings("unchecked")(所以我通過一個unchecked Unit而不是Unit<?>),並且一切都按預期工作,但我只是好奇這一點,我覺得禁止警告不是一件好事練習(是不是有點像空的catch塊?)。

謝謝!

編輯:添加一些代碼。

(對不起,這是相當長的,但在細節解釋了我卡上。)

我使用JSR-275version 0.9.4(最近)。

所以......如果我寫這篇文章(非常愚蠢的例子):

Measure measure = Measure.valueOf("3 m"); 
measure = Measure.valueOf(measure.doubleValue(Unit.valueOf("km")), Unit.valueOf("km")); 
System.out.println(measure); 

它的工作原理,並打印「0.0030公里」。但我收到警告「措施是原始類型。參考通用類型措施< Q>應參數化」在第一個Measure發生和警告「類型安全:方法doubleValue(單位)屬於原始類型可測量。參考通用類型可測量< Q>應參數化「超過measure.doubleValue(Unit.valueOf("km"))

看到這些警告,我想我可以調整這樣(只第一行):

Measure<Length> measure = Measure.valueOf("3 m"); 

然後我得到分配的「類型不匹配右側部分的錯誤消息:無法從度量轉換<捕獲#1 of?>測量<長度>「。它(Eclipse)爲我提供了正確的部分(Measure&lt;Length>)。但是然後我在右邊的部分得到警告信息「類型安全性:從措施<捕獲#1-of?>未檢查鑄造到措施<長度>」。修復建議:@SuppressWarnings,我寧願避免(因爲我猜測偏執狂的原因)。

因此,我回到Measure measure = Measure.valueOf("3 m");並試圖給通配符Measure,很明顯,它不知道「3米」在這一刻意味着什麼。它可能是Length,也可能是MassTime。所以我得到:

Measure<?> measure = Measure.valueOf("3 m"); 

並沒有警告或錯誤在這一行;太棒了。但是,在第二行:

measure = Measure.valueOf(measure.doubleValue(Unit.valueOf("km")), Unit.valueOf("km")); 

我得到與錯誤消息doubleValue:?「在類型的方法的doubleValue(?單位<捕獲#3的>)可測量<捕獲#3的>不適用於參數(Unit < capture#4 of?>)「。它建議將Unit.valueOf("km")作爲(Unit<?>)。精細。 「類型Measurable < capture#3-of?>中的方法doubleValue(Unit < capture#3 of?>)不適用於參數(單元< capture# 5-of>)「。注意數字已經改變了,所以這不是完全相同的參數,但是類似的原因。然後它執行完全相同的建議,導致代碼中無任何改變,因爲它已經完成。

所以這就是竊聽我。獲得它的唯一方法似乎是@SuppressWarnings或者只是忽略它們。這不奇怪嗎?

+4

你有一些我們可以看到的實際代碼嗎?泛型是非常「魔鬼的細節」。 – 2010-01-27 22:32:34

+0

我同意克里斯。你可以通過'Unit '而不是'Unit '來解決你的問題,但沒有代碼就很難說。 – 2010-01-27 22:37:07

+0

對不起,延遲,做不了更快。我寫了一個示例代碼,因爲我認爲在現實生活中與這個混合的一百行代碼並不相關。 – Joanis 2010-01-28 02:50:14

回答

3

請問措施類是這個樣子?

class Measure<T> { 

    double doubleValue(Unit<T> unit) { 
    ... 
    } 

} 

在這種情況下,具有的Measure<?>引用類型並不意味着你被允許任何類型的Unit傳遞到doubleValue方法。相反,這意味着Measure實例具有未知的泛型類型,並且將Unit傳遞給doubleValue方法是不安全的,因爲編譯器無法確保這些類型是兼容的。

通配符確實不是的意思是「任何類型」;它意味着「未知類型」。


更新:

valueOf(CharSequence)返回未知類型的Measure —一個Measure<?>。要將其安全地轉換爲您所期望的Measure類型,您必須使用Measure.asType()方法。與目標Unit同樣,由Unit.valueOf(CharSequence)方法創建。

Measure<?> unknownMeasure = valueOf("3 m"); 
Unit<?> unknownUnit = Unit.valueOf("km"); 
Measure<Length> length = unknownMeasure.asType(Length.class); 
Unit<Length> kilometer = unknownUnit.asType(Length.class); 
length.doubleValue(kilometer); 

請看Measure類文檔中的示例。他們將提供一些額外的深度。

+0

我不是100%確定這些類是如何定義的。這個庫有一個問題,就是我們有最新的代碼,但是我們找不到相同的版本API,也沒有相同的版本代碼。那麼,對於代碼來說,是的,但是由於某些原因它與字節碼類不相同......(某些功能和方法簽名不一樣)。 – Joanis 2010-01-28 02:56:16

2

Java泛型中的通配符表示「未知類型」。在這裏,您將doubleValue()方法定義爲接受Unit<something1>,其中方法未指定something1。然後您傳遞一個值,呼叫者知道Unit<something2>對於某些未知的something2。編譯器錯誤信息意味着沒有什麼能保證something1something2指定相同的東西。

試試這個:

<T> double doubleValue(Unit<T> unit) 
{ 
    ... 
} 

這意味着doubleValue()不關心什麼T是。

0

我無法重現你的問題,即以下編譯罰款(至少與Eclipse):

static double doubleValue(Unit<?> unit) { 
    return 0; 
} 

static void bla(Unit<?> u) { 
    doubleValue(u); 
} 

public static void main(String[] args) { 
    doubleValue(new Unit<String>()); 
} 
1

爲了擴展其他(優秀)的答案,但要多一點JSR-275具體(我目前正在使用它的項目)。

這一點很有趣

修復建議:我希望避免@SuppressWarnings(偏執的原因,我猜)。

你是正確的偏執,但仔細想想:你告訴Measure類來分析任意String,並返回任何類型的Measure。顯然在這種情況下,你可能會得到Measure<Length>(你可能會通過「3公斤」),所以留給圖書館的唯一選擇是返回Measure<?>。如果你想要一個Measure<Length>,那麼你必須強迫它以某種方式 - 這在編譯時不能保證安全。

在這種情況下,我會認爲@SuppressWarnings是完全可以接受的,假設你知道該字符串總是有效的長度。如果不是的話,那麼你遲遲不可避免地會出現ClassCastException,這很糟糕。

更好(萬歲!)JSR-275確實給你解決的辦法,這推動錯誤處理「正確」的地方(在獲得Measure,而不是在某個點之後,當時間它被使用)。嘗試

Measure<Length> = Measure.valueOf("3 m").asType(Length.class); 

asType返回Measure適當的通用版本,或失敗的異常,如果解析單元的尺寸不是長 - 這是幾乎可以肯定,你想要什麼,對不對?

我認爲這解決了您的問題。

+0

你說得對,'.asType()'可以解決這個問題。確實很好的答案。 但是,就我而言,我仍然遇到問題,因爲我的JSR-275庫的擴展支持不同數量之間的轉換。例如,在光學領域,我們直接在nm,THz,Ky等之間進行轉換,所以我不能強制我的措施使用類型...但這是另一回事。謝謝! – Joanis 2010-01-28 16:42:09

相關問題