近来看到一些代码,方法声明的异常竟然泛型化了,从没这么用过,请问这有什么好处?也不能catch泛型化的异常在网上搜到一个例子:package mytest;import java.util.*;public class ThrowGenericException { public static void main(String[] args) {
ProcessRunner<String, Failure1> runner = new ProcessRunner<String, Failure1>();
for (int i = 0; i < 3; i++)
runner.add(new Processor1());
try {
System.out.println(runner.processAll());
} catch (Failure1 e) {
e.printStackTrace();
} ProcessRunner<Integer, Failure2> runner2 = new ProcessRunner<Integer, Failure2>();
for (int i = 0; i < 3; i++)
runner2.add(new Processor2());
try {
System.out.println(runner2.processAll());
} catch (Failure2 e) {
e.printStackTrace();
}
}
}interface Processor<T, E extends Exception> {
void process(List<T> resultCollector) throws E;
}class ProcessRunner<T, E extends Exception> extends ArrayList<Processor<T, E>> {
List<T> processAll() throws E {
List<T> resultCollector = new ArrayList<T>();
for (Processor<T, E> processor : this)
processor.process(resultCollector);
return resultCollector;
}
}class Failure1 extends Exception {
}class Processor1 implements Processor<String, Failure1> { static int count = 3; public void
process(List<String> resultCollector) throws Failure1 {
if (count-- > 1)
resultCollector.add("Hep!");
else
resultCollector.add("Ho!");
if (count < 0)
throw new Failure1();
}}class Failure2 extends Exception {}class Processor2 implements Processor<Integer, Failure2> { static int count = 2; public void
process(List<Integer> resultCollector) throws Failure2 {
if (count-- == 0)
resultCollector.add(47);
else {
resultCollector.add(11);
}
if (count < 0)
throw new Failure2();
}}
ProcessRunner<String, Failure1> runner = new ProcessRunner<String, Failure1>();
for (int i = 0; i < 3; i++)
runner.add(new Processor1());
try {
System.out.println(runner.processAll());
} catch (Failure1 e) {
e.printStackTrace();
} ProcessRunner<Integer, Failure2> runner2 = new ProcessRunner<Integer, Failure2>();
for (int i = 0; i < 3; i++)
runner2.add(new Processor2());
try {
System.out.println(runner2.processAll());
} catch (Failure2 e) {
e.printStackTrace();
}
}
}interface Processor<T, E extends Exception> {
void process(List<T> resultCollector) throws E;
}class ProcessRunner<T, E extends Exception> extends ArrayList<Processor<T, E>> {
List<T> processAll() throws E {
List<T> resultCollector = new ArrayList<T>();
for (Processor<T, E> processor : this)
processor.process(resultCollector);
return resultCollector;
}
}class Failure1 extends Exception {
}class Processor1 implements Processor<String, Failure1> { static int count = 3; public void
process(List<String> resultCollector) throws Failure1 {
if (count-- > 1)
resultCollector.add("Hep!");
else
resultCollector.add("Ho!");
if (count < 0)
throw new Failure1();
}}class Failure2 extends Exception {}class Processor2 implements Processor<Integer, Failure2> { static int count = 2; public void
process(List<Integer> resultCollector) throws Failure2 {
if (count-- == 0)
resultCollector.add(47);
else {
resultCollector.add(11);
}
if (count < 0)
throw new Failure2();
}}
这样写,就是用户可以自己定义自己的异常,不影响整个主框架的程序处理比如说用户A, 他需要处理的类型是T1,自己定义了异常E1,用户B,他需要处理的类型是T1,自己也定义了异常E2,那么整个主框架不需要任何改变,都能对应
我的意思是说,如果你是针对多种接口做处理的话,可以不用管它是哪种异常,如果你是针对某种特定的接口处理,那么这个特定的异常你是能捕捉的。
如Processor<MyType, MyException> p = new Processor<MyType, MyException>() {
void process(List<MyType> resultCollector) throws MyException {
throw new MyException();
}
}try {
p.process(myList);
} catch (MyException e) {
System.out.println("用户可以捕获自己的异常");
}
public class ParentImpl implements Parent {
public void walk() throws RuntimeException {
System.out.println("I'm walking");
} public static void main(String[] args) {
new ParentImpl().walk();
}
}
interface Parent {
void walk() throws Exception;
}
你还是没明白,这里除了可以捕捉Exception,还可以捕捉自定义的Exception如果说是2个接口实现
p1<T1, Exception1>
p2<T2, Exception2>
你可以
try {
p1.process();
} catch (Exception1 e) {
....
}try {
p2.process();
} catch (Exception2 2) {
...
}如果接口统一抛出Exception,那么你就不能这样捕捉自己的异常了
你要写很多的catch,因为你不知道每个接口实现具体会抛出什么异常
而像上面的例子,可以很清楚地知道每个接口实现会抛出什么异常
这就是区别
还是用上面的例子来说
p<T1, E1>
try {
p.process();
} catch (Exception e) { //如果用范型,你已经知道p会抛出什么异常了,直接catch E1就可以了
if (e instanceof E1) {
((E1)e).printUserMsg();
} else {
e.printStackTrace();
}
}如果按你这么说,泛化本来就没意义,用Object就可以了,但为什么还是需要泛化,就是为了避免这些不必要的类型转换
如
List<String> list
因为我们知道list存的是String,所以我们直接
for (String s : list);
而没必要
for (Object o : list) {
String s = (String)o;
}
同样的道理
我们只到p<T1,E1>会抛出E1
我们直接
try {
p.process();
} catch (E1 e) {}
而没必要
try {
p.process();
} catch (Exception e) {((E1)e).xxx;}
如果一个方法抛出2个以上的异常不适用自定义异常,你就只能获得Exception类型的异常,如何根据具体的异常情况作出操作?就像LS阿宝说的那样,真不至于用 instanceof 这样吧= =
代码中异常的处理很重要,方便查出问题在哪?如果我们把同一类的异常泛型化,这样很容易排错.
泛型也有好处,ls说意思不大,这样说太绝对了.
void process(List<T> resultCollector) throws E;
}
这样用就是就限定了catch的异常类型,不能是error分支。如果没有error的话,上面这段话相当于脱裤子放屁了。呵呵....