タイプ消去/ジェネリックを適用して機能させる方法を見つけるのを手伝ってくれる人がいますか。
Set<? extends Object> ss = new HashSet<Integer>();
Set<? extends Object> sa = new HashSet<Integer>();
ss.addAll(sa);
コンパイル時に型をチェックするため、コンパイル エラーがスローされます。
まず、なぜそれが機能していないのか知っていますか?
これらは 2 つの別個のワイルドカードです。同じように見えますが、まだ別々です。したがって、最初の? extends Object
(実際には単純に書くことができます?
) は、2 番目とは単純に異なります。
また、ワイルドカードを使用しているときはいつでも、型を参照することを期待しないでください。addAll()
ただし、型チェックが必要な場合はそうしています。
メソッドにこれらのロジックがある場合は、メソッドに適切な型パラメーターを指定できます。
public static <T> void addToFirst(Set<T> first, Set<T> second) {
first.addAll(second);
}
そのため、型チェックを実行して、first と second が同じ型であることを確認できます。
生の型を使用することも別の選択肢かもしれません。
type パラメーターでワイルドカードを本当に使用する必要があるかどうかを自問してください。単純に使用するのSet<Integer>
は最も簡単なはずです。
タイプ消去されたソースは次のようになると考えることができると思います
Set ss = new HashSet();
set sa = new HashSet();
ss.addAll(sa); // compilation error
コンパイルされている場合
$ cat Erased.java
import java.util.*;
public class Erased {
public static void main(final String[] args) {
final Set<Integer> ss = new HashSet<Integer>();
final Set<Integer> sa = new HashSet<Integer>();
ss.addAll(sa);
}
}
$ javap -c Erased
Compiled from "Erased.java"
public class Erased {
public Erased();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/util/HashSet
3: dup
4: invokespecial #3 // Method java/util/HashSet."<init>":()V
7: astore_1
8: new #2 // class java/util/HashSet
11: dup
12: invokespecial #3 // Method java/util/HashSet."<init>":()V
15: astore_2
16: aload_1
17: aload_2
18: invokeinterface #4, 2 // InterfaceMethod java/util/Set.addAll:(Ljava/util/Collection;)Z
23: pop
24: return
}
これが逆コンパイルされたソースコードです
import java.util.HashSet;
import java.util.Set;
public class Erased
{
public static void main(String[] paramArrayOfString)
{
HashSet localHashSet1 = new HashSet();
HashSet localHashSet2 = new HashSet();
localHashSet1.addAll(localHashSet2);
}
}