Java——可选操作(UnsupportedOperationException)
最近在看《Java编程思想》第17章的时候,发现了一个新的名词—— 可选操作。
执行各种不同的添加和移除的方法在Collection接口中都是可选操作。这意味着实现类并不需要为这些方法提供功能定义。
读这部分的时候感觉很懵逼,不懂什么是可选操作。讲道理一个在接口中定义的方法,实现类在实现接口的时候都应该去提供对应方法的具体实现。这是在学习接口的时候建立的一种逻辑关系。但是此处好像说如果是可选操作的话就可以不用提供具体的实现。接着往下读
为什么你会将方法定义为可选的呢?那是因为这样做可以防止在设计中出现接口爆炸的情况。容器类库中的其他设计看起来总是为了描述每个主题的各种变体,而最终患上了令人困惑的接口过剩症。……未获支持的操作是一种特例,可以延迟到需要时再实现。但是,为了让这种方式能够工作:
1.UnsupportedOperationException必须是一种罕见事件。
2.如果一个操作是未获支持的,那么在实现接口的时候可能就会导致UnsupportedOperationException异常,而不是将产品程序交给客户以后才出现此异常,这种情况是有道理的。
这一段话好像是说增加这种特性是为了避免接口爆炸的情况,而且还特地举了容器的例子。确实不论是ArrayList还是Set中定义的方法是真的多。而且为了应用这种情况甚至设计了一种异常UnsupportedOperationException(名字可真够长的)。下面看一下书中给出的实际例子:
static void test(String msg,List<String> list){
System.out.println("--- " + msg + " ---");
Collection<String> c = list;
Collection<String> subList = list.subList(1,8);
Collection<String> c2 = new ArrayList<String>(subList);
try{ c.retainAll(c2); } catch(Exception e) {
System.out.println("retainAll(): " + e);
}
......//后面的省略了
}
public static void main(String[] args) {
List<String> list = Arrays.asList("A B C D E F G H I J K L".split(" "));
test("Modifiable Copy", new ArrayList<String>(list));
test("Arrays.asList()", list);
}
/*Output:
--- Modifiable Copy ---
--- Arrays.asList() ---
retainAll(): java.lang.UnsupportedOperationException
*///:~
从这份代码里面我们去研究一下,不同的只是传入的参数,一个直接把Arrays.asList()方法的结果当作参数传入;另外一个则是重新new 了一遍ArrayList()的对象并将其当作参数传入。
去看一下源码:
从源码中我们可以清楚的看见,Arrays.asList()方法是在Arrays类中重新new了一个ArrayList类的对象,并且其中并没有包含所有的方法。而第一种传参明显就是new了一个完全崭新的ArrayList类的对象。这也就是会出现UnsupportedOperationException异常的原因。
此处仅作为学习的笔记记录,如有不对的地方欢迎评论指正!