2

たとえば、指定されたで表される測定値Measure.doubleValue(Unit<?> unit)を返すメソッドを使用します。変数を渡すと、まだ非常に不可解な(私にとって)エラーメッセージが表示されます。doubleUnitUnit<?>

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")チェックを外して渡す)、すべてが期待どおりに機能しますが、これについては興味があり、警告を抑制することは良い習慣ではないように感じます(isn'空のキャッチブロックのようなものですか?)UnitUnit<?>

ありがとう!

編集:いくつかのコードを追加します。

(申し訳ありませんが、これはかなり長いですが、それは私が立ち往生していることを詳細に説明しています。)

JSR-275 バージョン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.0030km」を印刷します。しかし、「メジャーはraw型です。ジェネリック型Measure <Q>への参照はパラメーター化する必要があります」というMeasure警告が表示されます。「型の安全性:メソッドdoubleValue(Unit)はraw型Measurableに属します。ジェネリック型への参照Measurable <Q>は、パラメータ化する必要がありますmeasure.doubleValue(Unit.valueOf("km"))

これらの警告を見て、私はこのように調整できると思いました(最初の行のみ):

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

そして、割り当ての右側に「タイプの不一致:Measure <capture#1-of?>からMeasure<Length>に変換できません」というエラーメッセージが表示されます。It(Eclipse)は、適切な部分をにキャストすることを提供します(Measure&lt;Length>)。しかし、右側の部分に警告メッセージが表示されます。「タイプセーフティ:チェックされていないキャストをMeasure <capture#1-of?>からMeasure<Length>に」。提案された修正:@SuppressWarningsこれは避けたいと思います(私が推測するパラノイアの理由で)。

それで、私は戻ってMeasure measure = Measure.valueOf("3 m");ワイルドカードを付けようとしますMeasure。明らかに、現時点では「3m」が何を意味するのかわかりません。である可能性がありますがLengthMassまたはである可能性もありTimeます。だから私は得る:

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

そして、この行には警告やエラーはありません。素晴らしい。しかし、2行目:

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

次のエラーメッセージが表示されますdoubleValue: " Measurable <capture#3-of?>型のメソッドdoubleValue(Unit <capture#3-of?>)は、引数(Unit <capture#4-of?>)には適用できません。 ) "。Unit.valueOf("km")としてキャストすることをお勧めし(Unit<?>)ます。罰金。今、まったく同じ場所にエラーメッセージが表示されます: " Measurable <capture#3-of?>型のメソッドdoubleValue(Unit <capture#3-of?>)は、引数(Unit <capture#5 -の?>) "。数値が変更されていることに注意してください。これはまったく同じパラメータではありませんが、同様の理由です。次に、それはすでに行われているので、コードに何の変更ももたらさないまったく同じ提案を行います。

それが私を悩ませているものです。それを機能させる唯一の方法は、@SuppressWarningsそれらを無視するか、単に無視するようです。変じゃないですか?

4

4 に答える 4

3

メジャー クラスは次のようになりますか?

class Measure<T> {

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

}

その場合、参照型を持っていても、メソッドMeasure<?>に任意の型を渡すことが許可されているわけではありません。むしろ、インスタンスに不明なジェネリック型があり、型に互換性があることをコンパイラが保証できないため、そのメソッドに a を渡すのは安全ではないことを意味します。UnitdoubleValueMeasureUnitdoubleValue

ワイルドカードは「任意の型」を意味しません。それは「未知のタイプ」を意味します。


アップデート:

valueOf(CharSequence)不明なタイプのMeasure—aを返しますMeasure<?>。これを期待する型に安全に変換するには、メソッドMeasureを使用する必要がありますMeasure.asType()。メソッドUnitによって作成された target も同様です。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クラスのドキュメントの例を見てください。それらは、追加の深さを提供します。

于 2010-01-27T23:23:52.287 に答える
2

Javaジェネリックのワイルドカードは、「不明なタイプ」を意味します。ここでは、メソッドで指定されていない場合に、doubleValue()を受け入れるものとしてメソッドを定義します。次に、呼び出し元が不明な値について知っている値を渡します。コンパイラのエラーメッセージは、とが同じものを指定することを保証するものが何もないことを意味します。Unit<something1>something1Unit<something2>something2something1something2

これを試して:

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

つまり、それは何であるかをdoubleValue() 気にしませんT

于 2010-01-27T22:36:58.280 に答える
1

他の(優れた)回答を拡張しますが、もう少しJSR-275固有のものにしてください(現在、プロジェクトに使用しています)。

このビットは興味深いです

提案された修正: @SuppressWarnings は避けたいと思います (偏執的な理由からだと思います)。

あなたは偏執狂的ですが、それについて考えてみてください:Measureクラスに任意の を解析し、任意の型Stringの a を返すように指示しています。Measure明らかにその場合、Measure<Length>(「3 kg」を渡す可能性があります)を取得する場合と取得しない場合があるため、ライブラリに残された唯一のオプションは returnMeasure<?>です。が必要な場合はMeasure<Length>、何らかの形でそれを 1 つに強制する必要があります。これは、コンパイル時に安全であると保証できない可能性があります。

この場合、文字列が常に有効な長さであることがわかっていると仮定すると、 @SuppressWarnings は完全に受け入れられると主張します。そうでない場合は、避けられない事態を後回しにすることになりますClassCastException。これはかなり悪いことです。

しかし、さらに良いことに (万歳!) JSR-275 はこれを回避する方法を提供します。これにより、エラー処理が「適切な」場所にプッシュされます (Measure使用された後のある時点ではなく、 を取得する時点で)。試す

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

asTypeの適切な一般的なバージョンを返すMeasureか、解析された単位の次元が長さでない場合は例外で失敗します。これはほぼ確実にあなたが望むものですよね?

これで問題は解決すると思います。

于 2010-01-28T04:50:02.740 に答える
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>());
}
于 2010-01-27T22:48:59.047 に答える