public class MyGeneric<T, E> {}
public class Extend1<T, E> extends MyGeneric<T, E> {}
public class Extend2 extends MyGeneric<String, Object> {}
私の知る限り、上記の例のサブクラスは両方とも有効です。 Javaは、サブクラスがインスタンス化されるときにスーパークラスで指定された型がいつ定義され、実際のクラス名であるかをどのように知るのか(つまり、T、Eクラス名ではない)?
補足説明として、ジェネリック型に複数の文字を使用することは(たとえ一般的ではないにしても)許されますか? (計画の重大なエラーにより)型が既存のクラスと競合する場合.
public class E{}
public class Foo<E>{}
それではどうなりますか?
編集:すぐに答えてくれてありがとう。最初の質問に答えるには、 Joachimの答え が最も効果的です。
サイドポイントに答えるために、 aioobeの答えはより明確です
この定義を見てみましょう:
public class Extend1<T, E> extends MyGeneric<T, E> {}
ここで、T
とE
はそれぞれ2回、2つの異なる役割で存在します
Extend1<T,E>
youdefine型引数。これは、タイプExtend1
には、2つの(無制限の)型引数T
およびE
があります。 これは、Javaコンパイラに、useExtend1
タイプを指定する必要があります。extends MyGeneric<T,E>
youuse以前に定義された型引数を使用します。ここでT
とE
が型引数として知られていない場合、T
とE
は単純な型参照になります。つまり、コンパイラはクラスを探します(またはインターフェイス、...)という名前のT
およびE
(ほとんどの場合、それらは見つかりません)。はい、型引数はJavaの他の識別子と同じ構文規則に従うため、複数の文字ABC
を使用することも、混乱を招く名前を使用することもできます(String
という型引数を使用することは、しかし、非常に紛らわしい)。
単一文字型の引数名は、非常に一般的な命名戦略です。
サブクラスがインスタンス化されるとき、および実際のクラスであるときに、スーパークラスで指定された型がいつ定義されるかをJavaがどのように知るのか疑問に思っていました名前(つまり、T、Eがクラス名ではないことをどのように知っていますか?)
Javaは気にしません。もしあなたがそうするなら...
class MyGeneric<String> extends ArrayList<String> {
String value;
}
ジェネリック型に複数の文字を使用することは(たとえ珍しいとしても)許容されますか? (計画の重大なエラーにより)型が既存のクラスと競合する場合(例:
はい、型パラメーターには任意の有効なJava識別子を使用できます。
名前は競合する可能性がありますが、Javaはこれをエラーとして扱いません。 <
...>
間の識別子は、識別子がクラス名に対応するかどうかに関係なく、常に型パラメーターとして扱われます。
しかし、かなり混乱するかもしれません。次に例を示します。
class MyGeneric<String> extends Java.util.ArrayList<String> {
String value;
}
class Test {
public static void main(String... args) throws Exception {
MyGeneric<Integer> obj = new MyGeneric<Integer>();
obj.value = 5;
// ^
// |
// '--- Assign an integer to what seems to be a String!
}
}
同様の質問:
問題ありません:
public class E{}
public class Foo<E>{}
Foo<E>
のコンテキストでは、E
は型であるためです。