近来看到一些代码,方法声明的异常竟然泛型化了,从没这么用过,请问这有什么好处?也不能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();
    }}

解决方案 »

  1.   

    不需要catch泛化异常,只要catch Exception就可以了,因为 E是extends Exception的
    这样写,就是用户可以自己定义自己的异常,不影响整个主框架的程序处理比如说用户A, 他需要处理的类型是T1,自己定义了异常E1,用户B,他需要处理的类型是T1,自己也定义了异常E2,那么整个主框架不需要任何改变,都能对应
      

  2.   

    没错,类型是可以任意定义,但和直接声明throws Exception相比,这有什么显著优点吗?
      

  3.   

    当然有了
    我的意思是说,如果你是针对多种接口做处理的话,可以不用管它是哪种异常,如果你是针对某种特定的接口处理,那么这个特定的异常你是能捕捉的。
    如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("用户可以捕获自己的异常");
    }
      

  4.   

    接口方法声明为throws Exception,实现类的方法也可以抛出任意异常啊。
    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;
    }
      

  5.   

    你究竟问的是 throws 和 try catch 的区别还是问Exception 和 MyException 的区别?
      

  6.   


    你还是没明白,这里除了可以捕捉Exception,还可以捕捉自定义的Exception如果说是2个接口实现
    p1<T1, Exception1>
    p2<T2, Exception2>
    你可以
    try {
        p1.process();
    } catch (Exception1 e) {
        ....
    }try {
        p2.process();
    } catch (Exception2 2) {
        ...
    }如果接口统一抛出Exception,那么你就不能这样捕捉自己的异常了
    你要写很多的catch,因为你不知道每个接口实现具体会抛出什么异常
    而像上面的例子,可以很清楚地知道每个接口实现会抛出什么异常
    这就是区别
      

  7.   

    使用范型是直观一些,不过,从语义上讲,声明exception,你仍然可以catch具体的exception。好处我觉得还是不明显。
      

  8.   

    补充:我觉得你使用某个类的时候,即使声明成了throws exception,你应该也知道实际会抛出啥类型的具体exception,所以,范型意义不大。
      

  9.   

    你这么看看不出什么意义,这里不光是直观,如果你这个自己写的EXXX有很多Exception所没提供的方法或信息,那么你只catch exception,你还要自己判断是什么EXXX,即 e instanceof EXXX,然后再强行转换为实际的Exxx,然后再调用方法获取信息,这样就显得不简练了。
    还是用上面的例子来说
    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;}
      

  10.   


    如果一个方法抛出2个以上的异常不适用自定义异常,你就只能获得Exception类型的异常,如何根据具体的异常情况作出操作?就像LS阿宝说的那样,真不至于用 instanceof 这样吧= =
      

  11.   

    方法声明的异常竟然泛型化了.这样写的好处是可以统一处理异常,如果程序多处抛出泛型异常,比较烦躁.如果程序到处都是异常,如果仅仅使用最大的异常Exception不好管理和维护.
    代码中异常的处理很重要,方便查出问题在哪?如果我们把同一类的异常泛型化,这样很容易排错.
    泛型也有好处,ls说意思不大,这样说太绝对了.
      

  12.   

    java的异常的基类是个借口throwable。然后两个分支 error 和 exception。interface Processor<T, E extends Exception> {
        void process(List<T> resultCollector) throws E;
    }
    这样用就是就限定了catch的异常类型,不能是error分支。如果没有error的话,上面这段话相当于脱裤子放屁了。呵呵....