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);
     ....
 }

虽然静态类型可以阻止我们在需要可修改列表的情况下使用不可修改列表,但反之则不然。每个 List 也是一个 UnmodifiableList ......这没有任何意义。

备选方案 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

它是 的内部类Collections,因为Collections它是不可实例化的,并且是具有包可见性的内部类,所以你无法访问该类,它是隐藏在 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.unmodifiableList%28java.util.List%29

这是一个内部类Collections

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

您的声明清楚地表明它仍然引用 List,但它禁止修改列表。

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

如果您共享不可修改的列表引用,请确保没有人更改它并允许只读操作。

于 2012-05-07T10:15:43.900 回答
0

调试显示运行时类型是Collections.UnmodifiableRandomAccessList,所以它是内部类。代码分析也表明它可能是Collections.UnmodifiableList.

你不应该尝试访问这个类,它应该是不可变的。尝试使用通用接口,在这种情况下 = Collection

于 2012-05-07T10:09:43.220 回答