0

タイトルは基本的にそれをすべて言います: T でジェネリックな Java メソッドを持っている場合、T について何かを知ることができますか? 特に、T が特定のインターフェイスを実装しているか、特定のクラスを拡張しているかを確認できますか?

私は次のようなことをしたいと思います

public <T> List<T> doSth(List<T> l) {

  if(T extends Comparable) {
    // do one thing
  } else {
    // do another
  }

  return l;
}

ヒントはありますか?

どうもありがとう、

ヨハネス

4

6 に答える 6

10

コンパイル時または実行時にチェックを実行するかどうかは明確ではありません。メソッドに渡されるリスト パラメータに特定のタイプのオブジェクトが含まれていることを確認したいだけの場合は、T適切に再定義してください。

たとえば、コンパイラが a のみList<Comparable>をこのメソッドに渡すことを許可するようにするには、次のように再定義Tします。

public <T extends Comparable<? super T>> List<T> doSth(List<T> l) {
    // Method body omitted
}

次に、(if-else ステートメントの代わりに) メソッドのオーバーロードを使用して、 の任意の値に対して正しいコードが呼び出されるようにしますT。つまり、これを置き換えます。

public <T> List<T> doSth(List<T> l) {

    if(T extends Comparable) {
        // do one thing
    } else {
        // do another
    }

    return null
}

これ等と一緒に:

public <T extends Comparable<? super T>> List<T> doSth(List<T> l) {
    // do one thing
    return null;
}

public <T> List<T> doSth(List<T> l, Class<T> clazz) {
    // do another
    return null;
}

ただし、呼び出すオーバーロードされたメソッドを選択することと、ジェネリック型のチェックはコンパイル時のみであることを覚えておく必要があります。たとえば、次のコード:

List<? extends Serializable> alist = new ArrayList<Integer>();
doSth(alist);

実行時の型パラメーター ( ) は実装していますが、コンパイル時の型パラメーター ( ) は実装していないdoSthため、実際には 2 番目のメソッドを呼び出します。? extends SerializableComparableInteger

于 2009-10-13T16:58:23.743 に答える
4

いいえ -型消去のため。実行時には、T の型はまったくわかりません。

1 つのオプションは、型を別のパラメーターとして指定することです。

public <T> List<T> doSth(List<T> l, Class<T> clazz) {
    if (Comparable.class.isAssignableFrom(clazz)) {
        ...
    }
}
于 2009-10-13T16:52:55.943 に答える
1

はい、次のことができます。

public <T> List<T> doSth(List<T> l) {
  //You could also check every element, if there is a chance only some will be comparable
  if (l.size() >0 && l.get(0) instanceof Comparable) {
    // do one thing
  } else {
    // do another
  }

  return l;
}

「l」の要素がどのタイプであるかを確認していることに注意してください。Tではありません-それがキーです。

編集:リストであるという事実を処理するようにコードを変更しました-最初の読書ではそれを見逃していました。

于 2009-10-13T16:54:04.157 に答える
1

T が Comparable を拡張するかどうかはコンパイル時に (それよりも前に! :) 知っているはずなので、2 つのメソッドを作成してみませんか?

public <T extends Comparable<T>> List<T> doSthComp(List<T> l) {
  // do one thing
  return l;
}

public <T> List<T> doSth(List<T> l) {
  // do another
  return l;
}
于 2009-10-13T17:06:25.870 に答える
0

あなたはすることができます

public <T extends Comparable<T>> List<T> doSth(List<T> l)

これにより、アイテムで Comparable インターフェイスを使用できるようになります'l'

于 2009-10-13T16:59:57.787 に答える
0

コンパイル時のチェックについては、ドンはすでに答えを出しています。ランタイムでは、T を表す明示的なオブジェクトも渡す場合にのみ可能です。たとえば、
static <T> List<T> doSth(List<T> l, Class<T> tClass) T の実際のクラスを表す tClass オブジェクトを使用すると、リフレクションを介して同等のものを実装しているかどうかを確認できます。しかし、コンパイル時のチェックは、私の観点からははるかに優れています。

于 2009-10-13T17:04:33.607 に答える