因为不管是在编译期还是在运行期,想要用catch捕获异常都必须要知道一异常的确切类型,所以泛型中异常的使用是非常受限制的,当然泛型类不能继承Throwable。但是throws子句是可以用到泛型参数的,下面直接上代码:
import java.util.*;
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();
}
}
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){
System.out.println(e);
}
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){
System.out.println(e);
}
}
}
这是一段比较长的代码,我先用介绍一下其中用到的类及其方法:Failure1,Failure1都是继承了Exception的类。
Processor是一个接口,其中有一个process的方法,processor1,processor2继承了这个接口并实现了process方法。
然后有一个ProcessRunner类继承了ArrayList<Processor<T,E>>,runner1,runner2分别是ProcessRunner<String, Failure1>,ProcessRunner<Integer, Failure2>的实现,runner1用于测试processor1,runner2用于测试processor2。
在异常中使用泛型,可以增加我们对异常捕获的能力,也可以更加确定异常发生的原因。对比下面没有在异常中使用泛型的代码:
import java.util.*;
interface Processor<T>
//注意Processor这里并没有使用泛型异常了
{
void process(List<T> resultCollector) throws Exception;
}
class ProcessRunner<T>
extends ArrayList<Processor<T>>
{
List<T> processAll() throws Exception
{
List<T> resultCollector = new ArrayList<T>();
for(Processor<T> processor : this)
{
processor.process(resultCollector);
}
return resultCollector;
}
}
class Failure1 extends Exception{}
class Processor1 implements Processor<String>
{
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>
{
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();
}
}
public class ThrowGenericException
{
public static void main(String[] args)
{
ProcessRunner<String> runner = new ProcessRunner<String>();
for(int i=0; i<3; i++)
{
runner.add(new Processor1());
}
try{
System.out.println(runner.processAll());
}catch(Exception e){
//注意这里的区别
System.out.println(e);
}
ProcessRunner<Integer> runner2 = new ProcessRunner<Integer>();
for(int i=0; i<3; i++)
{
runner2.add(new Processor2());
}
try{
System.out.println(runner2.processAll());
}catch(Exception e){
//注意这里的区别
System.out.println(e);
}
}
}
这个时候我们只能捕获Exception类型的异常,而不能捕获具体类型的异常。