2

我制作了一个抽象线程,在其 run() 方法中处理一些流。我希望能够让子类而不是抽象父类处理这些异常,但我不知道最优雅的方法。现在,我正在做这样的事情:

import org.apache.logging.log4j; // (I use log4j for logging)

public interface Loggable {
     Logger getLogger();
}

public abstract class ParentThread extends Thread implements Loggable {
    private final static Logger logger =
      Logger.getLogger(ParentThread.class); // Logger with no Appenders

    @Override
    public void run() {
        try {
            // Do some stuff that throws exceptions
            doAbstractStuff();
        } catch (SomeSortOfException ex) {
            getLogger().error("Oh noes!", ex);
        } catch (SomeOtherException ex) {
            getLogger().error("The sky is falling!", ex);
        }
    }

    public Logger getLogger() { return logger; }

    protected abstract void doAbstractStuff();
}

public class ChildThread extends ParentThread {

    @Override
    public Logger getLogger() { /* return a logger that I actually use */ }

    @Override
    public void doAbstractStuff() { /* Implementation */ }
}

我想我应该提到 ChildThread 实际上是我的主窗体的内部类,并且它的记录器属于该窗体。

我想到的另一种方法是

abstract void handleException(Exception ex);

在 ParentThread 中,但是我无法处理来自 ChildThread 的单个异常。

4

3 回答 3

0

嗯,没有区别

} catch (SomeSortOfException ex) {
    getLogger().error("Oh noes!", ex);
} catch (SomeOtherException ex) {
    getLogger().error("The sky is falling!", ex);
}

if (ex instanceof SomeSortOfException) {
    getLogger().error("Oh noes!", ex);
} else if (ex instanceof SomeOtherException) {
    getLogger().error("The sky is falling!", ex);
}

尽管后者可能需要一些铸造。

你的abstract handleException(Exception ex)想法是合理的,我会同意的。不过,我倾向于不做abstract,并在 中定义一个合理的默认实现ParentThread,并允许ChildThread在需要时覆盖它。

于 2011-04-23T09:43:05.140 回答
0

您的第一个解决方案在我看来在概念上是错误的:将特定于应用程序的错误处理与通用日志记录混合。

您的第二个想法(回调)似乎是一个更好的解决方案,并提供了为自定义事件抽象出特定于实现的异常的可能性,例如:

public abstract class Parent {

    public void run() {

        InputStream in = null;    
        try {
            in = new URL("bladiebla").openConnection().getInputStream();    
            String text = // ...read text from InputStream     
            if (text == null || text.length() == 0) {
                handleMyEvent(new NoInputEvent());
                return;
            }           
            doWork(text);
        } catch (MalformedURLException e) {
            handleMyEvent(new MyEvent(e));                
        } catch (IOException e) {
            handleMyEvent(new MyEvent(e));
        }
        finally {
            if (in != null) {
                try {
                    in.close();
                }
                catch(IOException e) {
                    handleMyEvent(e);
                }
            }
        }
    }            

    abstract void doWork(String text);

    abstract void handleMyEvent(MyEvent myEvent);
}

public class MyEvent {
    private Exception exception;
    public MyEvent() {}
    public MyEvent(Exception exception) {//set it}
}

public class NoInputEvent extends MyEvent {        
}
于 2011-04-23T11:05:11.173 回答
0

为什么你的基类记录异常?为什么不使用平台提供的 Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) 并让它做任何事情,而不是将日志记录与您的 do-stuff 组件混合。

于 2011-04-23T11:17:31.613 回答