2016-04-15 22 views

答えて

4

私はこれが警告の理由だと考えています。Javaではダウンキャストが可能です。すなわち、X型のオブジェクトをXのサブクラスにキャストします。ただし、実行時にチェックが必要です。たとえば:

Object x1 = <... something that returns an object that may be a String ...>; 
String x2 = (String)x1; 

キャストがStringとしてx1を扱うしようとします。しかし、x1は任意のObjectになります。 Stringである場合とそうでない場合があります。キャストはx1が実際にStringの場合にのみ有効です。そうでなければ、実行時にClassCastExceptionが得られます。

Tのサブクラスは、Viewのサブクラスであり、これは通常、実行時に同じ種類のチェックが実行されることを意味します。ただし、タイプ消去のため、コードのこの時点でプログラムは実際にTのクラスに関する情報を持っていません。つまり、チェックを実行できません。したがって、チェックされていない操作を使用しているプログラムについての警告が表示されます。このメソッドが返すとき、返されたオブジェクトは実際にはクラスTのインスタンスになることは保証できません。

いくつかのテストケースを試したところ、が汎用メソッドをと呼ぶという発言でよくチェックが行われました。 View2Viewに拡張されていて、を返すようにfindを使用するとします。その後:findViewByIdで見つかったオブジェクトが本当にView2ない

View2 v = YourClass.<View2>find(x, id); 

場合は、ClassCastExceptionを取得します。しかし、

findViewByIdが別のビューを返すとします。私のテストに基づいて、型パラメータがView2であっても、これは例外をスローしません。これはViewに割り当てられます。結果が他のビューであれば正常に動作し、View2のチェックは行われません。

String s = YourClass.<View2>find(x, id).toString(); 

findViewByIdが別のビューを返すとします。私はこれを試してみたとき、他のビューにもtoString()(すべてObjectのようなもの)があるので、例外をスローしないと思った。しかし、これはClassCastExceptionを投げた。

私はそれを修正するための良い方法があるかどうかわかりません。一つの可能​​性はTのクラスを表すためにfindに三番目のパラメータを追加し、そのcastメソッドを使用することです:

この作品
public static <T extends View> T find(View view, int id, Class<T> theClass) { 
    return theClass.cast(view.findViewById(id)); 
} 

View v = YourClass.find(x, id, View2.class); 

からfindViewByIdが間違ったクラスを返すかどうかはcast()メソッドから例外がスローされます。ただし、コールから明示的なジェネリック型パラメータを削除することは可能ですが、すべての用途に第3のパラメータを追加することは魅力的ではないかもしれません。

これは、警告を無視して、警告が表示されないようにするために使用するといいと思うのですが、findViewByIdの場合に例外をスローするのではなく、プログラムが続行する可能性がある間違った種類のビューを返します。

免責事項:私のテストはJava 8を使用して実行されました。Java 7では有効ではないものは使用しませんでしたが、まだAndroid 7が完全にJava 7を実装していない場合、間違っている可能性があります)

関連する問題