6

Javaで変更できないリストは、次のように作成できます。

List<String> unModifiableStringList = Collections.unmodifiableList(myActualModifiableList);

これは問題ありませんが、上記の関数によって返されるリストの実際の実行時タイプは何ですか?どうすればそのクラスにアクセスできますか?それも可能ですか?

更新:実際には、コンパイル時に変更不可能なリストが変更されていることを知る必要があります。多くのリストを処理する必要があるため、変更可能なリストとそうでないリストがあります。それで、追跡するのは非常に面倒ですか?

4

6 に答える 6

9

実際、コンパイル時に、変更できないリストが変更されていることを知る必要があります。

それは不可能です。

または、少なくとも、完全に異なるコレクションインターフェイス/クラス階層を作成しないと不可能です。通常のコレクションを使用するように設計されたものは何も機能しないため、これは悪い考えです。

この種のことを検出できる静的コードアナライザーを作成することは可能だと思います...場合によっては...しかし、それは厳密には「コンパイル時」ではありません。その上、私はこれを「箱から出して」行う既存の静的コードアナライザーを知りません。


彼らがこのようにした理由はあったのだろうか。

さて、これを行う方法はどれも実際には機能しません。

代替案#1:

 public interface UnmodifiableList<T> {
     public T get(int pos);
     ....
 }

 public interface List<T> extends UnmodifiableList<T> {
     public void add(T elem);
     ....
 }

静的型付けは、変更可能なリストが必要な場合に変更不可能なリストを使用することを防ぐことができますが、その逆は当てはまりません。すべてのリストもUnmodizableListです...そしてそれは本当に意味がありません。

代替案2:

 public interface List <T> {
     public T get(int pos);
     public void add(T elem);
     ....
 }

 public interface UnmodifiableList<T> {
     // A marker interface
 }

これで、静的型付けにより、変更可能なリストが必要な場合に変更可能なリストを使用できなくなりますが、その逆はできません。(それはあなたの要件に合っています...)さらに、実装するクラスはUnmodifiableListまだ操作を継承しadd、アプリケーションがそれを呼び出そうとするのを止めるものは何もありません。

つまり、静的型システムでは、この種の制限を適切に処理できません。

于 2012-05-07T10:50:48.797 に答える
3

試しましたunModifiableStringList.getClass().getName()か?

私にそれは与える

java.util.Collections$UnmodifiableRandomAccessList

これは、ソースコードからわかるように、のパッケージアクセス静的内部クラスですCollections

于 2012-05-07T10:08:56.637 に答える
3

です

static class UnmodifiableList<E> extends UnmodifiableCollection<E>
                      implements List<E>

static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
                                      implements RandomAccess

static class UnmodifiableCollection<E> implements Collection<E>, Serializable

の内部クラスでありCollectionsCollectionsインスタンス化できず、パッケージの可視性を備えた内部クラスであるため、クラスにアクセスできず、OOPに隠れている実装です。

于 2012-05-07T10:12:10.430 に答える
2

参照: http: //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collections.java#Collections.unmodizableList%28java.util.List%29

これは次の内部クラスですCollections

static class UnmodifiableList<E> extends UnmodifiableCollection<E>
                                 implements List<E>
于 2012-05-07T10:09:12.920 に答える
0

デバッグは、ランタイムタイプがCollections.UnmodifiableRandomAccessListであると示しているので、それは内部クラスです。コード分​​析は、それがである可能性があることも示していますCollections.UnmodifiableList

このクラスにアクセスしようとしないでください。不変であることが意図されています。代わりに、共通のインターフェースを使用してみてください。この場合は=Collectionです。

于 2012-05-07T10:09:43.220 に答える
0

あなたの声明はまだリストの参照を明確に述べていますが、それはリストの変更を抑制します。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#unmodizableList(java.util.List

変更不可能なリスト参照を共有する場合は、誰もそれを変更しないようにし、読み取り専用操作を許可するようにします。

于 2012-05-07T10:15:43.900 に答える