10

このコードでは、型を として宣言できないのはなぜClass<? extends B>ですか?

public class Foo<B> {
    public void doSomething(B argument) {
        Class<? extends Object> type = argument.getClass();
    }
}
4

4 に答える 4

4

この問題は、Java の構文では getClass() が定義されたクラスに一致する型を返すと言うことができないことであり、これはコンパイラに関する限り特別なケースではありません。したがって、結果をキャストする必要があります。

連鎖などで型を指定できるようにしたい場合が多いthisので、いつかはこの機能を搭載してほしいです。

あなたは書くことができます

Class<? extends this> getClass();

また

public this clone(); // must return a type of this class.

また

class ByteBuffer {
    this order(ByteOrder order);
}

class MappedByteBuffer extends ByteBuffer {
}

// currently this won't work as ByteBuffer defines order()
MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, fc.size())
                         .order(ByteOrder.nativeOrder());
于 2012-12-06T09:02:55.293 に答える
0

Object.getClass() is defined to return a Class, where T is the statically known type of the receiver (the object getClass() is called on). Take special note of the vertical bars, the erasure operator. The erasure of a type variable is the erasure of its leftmost bound. In your case that's the implicit bound Object. So you get back a Class, not a Class<? extends T>.

The right way to do it is,

abstract class AbstractExecutor<E> {

public void execute() throws Exception {
    List<E> list = new ArrayList<E>();
    Class<E> cls = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    E e = cls.getConstructor(String.class).newInstance("Gate");
    list.add(e);
    System.out.println(format(list));
}

// ...

}

于 2012-12-06T09:03:12.070 に答える
0

特定のオブジェクトのクラスが、格納されている型と同じであるとは限らないためです。

例えば。

Object o = "some string";

Class<Object> clazz = o.getClass(); // actually Class<String>

タイプを見ると、 のクラスを期待する必要がありObjectますが、実際には のクラスを取得しますString。これはどのような問題ですか?Objectは のスーパークラスでStringあるため、Stringによって実装されるすべてのメソッドを実装しObjectます。

問題

問題は、クラスを取得するFieldと、ジェネリック型ではなく実際のクラスのフィールドが返されることです。さらにMethod、指定されたオブジェクトにオーバーライド メソッドがある場合、正しいメソッドを呼び出すことはできますが、その逆を行って、指定されたオブジェクトで機能するメソッドの実装を見つけることはできません。

たとえば、Object は を宣言しhashCodeているため、すべてのオブジェクトにハッシュ コード メソッドがあります。ただし、次の場合は実行時例外が発生します。

Object.class.getMethod("hashCode").invoke("some string"); // works
String.class.getMethod("hashCode").invoke(new Object()); // fails

これは、 のMethodオブジェクトhashCodeString. 文字のシーケンスからハッシュ コードを生成することを期待していますが、提供されたオブジェクトにはメソッドが動作するための char 配列がないため、失敗します。

getMethodつまり、次のように動作するように見えますが、 によって返される実際のメソッドが のハッシュ コード メソッドであるため、動作しませんString

Object obj = "string";
Class<Object> clazz = obj.getClass();
clazz.getMethod("hashCode").invoke("another string");
于 2012-12-06T10:25:22.333 に答える
0

これがすべてですgeneric type erasureここから:

ジェネリック型のすべての型パラメーターをそれらの境界またはオブジェクト (型パラメーターが無制限の場合) に置き換えます。したがって、生成されたバイトコードには、通常のクラス、インターフェース、およびメソッドのみが含まれます。【コンパイル時】

Classしたがって、実際の型を取得することはできませんが、 orBのみです。?? extends Object

<B extends SomeClass>境界が onlyではなくに変わる場合は、 type のオブジェクトを<B>フェッチできます。Class<? extends SomeClass>

于 2012-12-06T08:57:16.867 に答える