1

keySet() は java.util.Set を返します。NavigableSet へのキャストで ClassCastException がスローされないのはなぜですか? これは、実際のオブジェクトが java.util.Set 参照を持つ TreeSet である場合に発生する可能性があります。私にはそれが理解できません。

import java.util.*;
class A1{}
public class Main{
     public static void main(String args[]){
         SortedMap nvs=new TreeMap();
         nvs.put(1,"one");
         nvs.put(2,"two");
         nvs.put(3,"three");
         nvs.put(4,"four");
         NavigableSet nss=(NavigableSet)nvs.keySet();
         for(Object ob: nss){
              System.out.print(nvs.get(ob)+", ");
         }
     }
}
4

3 に答える 3

2

あなたの質問は、ポリモーフィズムを理解していないことを示しています。類推を使用しましょう。あなたはバーに行き、ビールを頼みます。そして、あなたはステラを手に入れます。あなたは具体的にステラを求めていませんでしたし、バーは彼らのビールが実際にステラビールであることを公表していませんでしたが、実際には、あなたが手に入れた実際の具体的なタイプのビールはステラでした. バーは、ビールを頼んだときにステラがもらえるとは限らないため、それに頼るべきではありません。バーの将来のバージョンでは、代わりにジュピラーが提供される可能性があるためです。ジュピラーとステラはどちらもビール。

あなたの質問と同じです。戻り値の型は Set であるため、任意の種類の Set を返すことができます。メソッドが実際に NavigableSet を返すことが javadoc で保証されていない限り、それに依存するべきではありません。

于 2012-12-07T20:11:24.740 に答える
2

最善の方法は、実際のコードを確認することですTreeMap(これは Java 1.7 のものです)。

public Set<K> keySet() {
    return navigableKeySet();
}

public NavigableSet<K> navigableKeySet() {
    KeySet<K> nks = navigableKeySet;
    return (nks != null) ? nks : (navigableKeySet = new KeySet(this));
}

KeySetクラス宣言は次のとおりです。

static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {...}

ご覧のとおり、メソッドは のスーパー インターフェイスであるTreeMap#keySet型を返します。そして、それから返される参照は、メソッドのようにインスタンスを指します。SetNavigableSetSetKeySetnavigableKeySet()

また、KeySetクラスは を実装NavigableSetしているため、そのインスタンスを指す参照をいつでも参照にキャストできますNavigableSet

メソッドの実装から独立していることを確認するために、keySet()単にメソッドを呼び出してキャストnavigableKeySet()を取得して回避することができますNavigableSet

于 2012-12-07T20:04:42.453 に答える
0

ClassCastException返されたオブジェクトがa であるため、 a を経由しませんNavigableSet。たとえば、返されたオブジェクトに対して getClass() メソッドを使用して出力できます。このクラスは、NavigableSetまたはそのサブクラスです。

デバッガー (Eclipse など) を使用して、オブジェクトのクラスを取得することもできます。

SortedMap.keySet()の仕様では、オブジェクトを返すことが示されているためSet、安全にキャストできない可能性がありますNavigableSet。他の実装、または実装の変更により、コードが につながる可能性がありますClassCastException

コンパイラはこれをチェックできないため、実行時にチェックが実行されます。

于 2012-12-07T19:59:19.297 に答える