3

次のコンストラクターPictureArrayAdapterを拡張して持つクラスがあります。ArrayAdapter<Pair<String, ImageInitialiser>>

public PictureArrayAdaptor(Context context, Pair<String, ImageInitialiser>[] values)

このコンストラクターが呼び出されると、プログラマーはを渡す必要があることを明示的に宣言しましたPair<String, ImageInitialiser>[]。そうしないと、型エラーが発生する可能性があります。現在、警告なしでそのようなオブジェクトを作成することはかなり困難です。

@SuppressWarnings("unchecked")
Pair<String, ImageInitialiser> tableData[] = new Pair[1];
tableData[0]=new Pair<String, ImageInitialiser>("A", new ResourceImageInitialiser(R.drawable.sample1));

1つの可能性は、代わりにリストを使用することです。ただし、一貫性を保つために、すべてのコンストラクターを基本クラスとまったく同じに保ちたいと思います。このコンストラクターを呼び出すためのより良い方法はありますか?私は本当にこれがそれが呼ばれることになっている方法であるとは思いません。

4

3 に答える 3

4

もう 1 つの方法は、Pair を拡張するクラスを作成することです。たとえば、

class NamedImage extends Pair<String, ImageInitialiser> { ... }
class PictureArrayAdapter extends ArrayAdapter<NamedImage> { ... }

NamedImage はreifiable型になったため、配列を免責のように使用できますNamedImage[]。さらに、チェックされていない例外を取り除き、すべての宣言を簡素化して、ネストされた型パラメーターを持たないようにします。

于 2012-08-15T03:52:21.020 に答える
2

配列とジェネリックは、油と水のようなものです。ジェネリック型の配列で型の安全性を保証することは不可能であるため、警告が表示されます。varargs ( ...) にも同じことが言えます。これは、暗黙的な配列の作成を伴うためです。理由の詳細な説明については、ジェネリック FAQを参照してください。

Listパラメータを配列ではなくa にすることを強くお勧めします。スーパー コンストラクターが配列を受け取る必要がある場合はtoArrayList. 一般に、コレクションは配列よりもはるかに汎用性が高く、絶対に必要でない限り、配列を直接使用するべきではないと考える人もいます。

于 2012-08-15T01:41:05.183 に答える
0

わかりました、私はしばらくそれについて考えました、そして、私がこれをしている方法はまさにそれをする方法であることに気付きました. 一般的なオブジェクトに関して言えば、リストは間違いなく使いやすいですが、一貫性を保つためにインターフェイスを一致させようとしています。

ジェネリックのチュートリアル(15 ページ) では、ジェネリック オブジェクトの配列を作成できない理由は、警告なしでランタイム タイプ エラーが発生する可能性があるためであると説明しています。

List<?>[] lsa = new List<?>[10]; // ok, array of unbounded wildcard type
Object o = lsa;
Object[] oa = (Object[]) o;
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[1] = li; // correct
String s = (String) lsa[1].get(0); // run time error, but cast is explicit

を使用する@SuppressWarnings("unchecked")ことで、このコードに触れるすべての人に、コンパイラに頼るのではなく、型の安全性について考えるように強制します。Python のような言語では、コンパイル時の型安全性がまったくないため、これは大した問題ではありません。@SuppressWarnings は、プログラマーが自分で管理しなければならないことを明確にしますが、これを見逃したとしても、実行時にキャッチされる可能性があります。

さて、コンストラクタについて考えてみましょう。ジェネリック配列変数とジェネリック配列引数の宣言にはそれほど違いがないため、これはコンパイラが警告を出すのに適した場所だと思います。ここでは、@SuppressWarnings はありませんが、型自体がプログラマーに十分な警告を与えると思います。さらに、このクラスを変更して型エラーが発生する危険を冒す方が、ジェネリック配列だけを使用して呼び出し元が型エラーを発生させる危険を冒すよりも優れています。

于 2012-08-15T02:26:38.753 に答える