バックグラウンド
この質問は、Java 開発者と Android 開発者の両方を対象としています。
Android では、Viewから拡張されたものを返し、 Checkableを実装する関数が必要です。どちらも Android API の一部です。
私が試したこと
ここやインターネット上の他の場所を少し検索した後、次の解決策を見つけました。
private <T extends View & Checkable> T get() {
return (T) mView;
}
mView は View を拡張する任意の型であることに注意してください (そしてたくさんあります) が、それらの型だけが存在するため、Checkable を実装することを保証します。
これは "Type safety: Unchecked cast from View to T" という警告を表示しますが、それは問題ではありません。問題は、この方法を正しく使用できないことです。たとえば、次のようになります。
View v=get(); //this works fine
Checkable c=get(); // this shows error
2 行目にエラーが表示されます。
範囲の不一致: タイプ ... の汎用メソッド get() は、引数 () には適用できません。推測されたタイプ Checkable&View は、境界付きパラメーターの有効な代替ではありません
そこで、「&」の代わりに「,」を使ってみました。同じエラー。
ただし、「、」を使用して順序を逆にすると、「The type parameter View is hide the type View」という警告が表示され、両方の行が正常に機能します。
これはコードです:
private <T extends Checkable, View> T get() {
return null;
}
private void foo() {
final View v = get(); // this works fine
final Checkable c = get();// this works fine too
}
ただし、返された型を他の関数に送信すると、クラスとインターフェイスを拡張するものとして型自体が取得されず、常に (View に) キャストする必要があります。
質問
それを行う正しい方法は何ですか?
最後に示した方法が正しい場合、なぜ警告が表示されるのですか? 拡張するクラスが常に 1 つの最大値である場合、なぜ順序が重要なのですか?