简体   繁体   English

从Java中的抽象Runnable.run()引发异常

[英]Throwing an exception from an abstract Runnable.run() in Java

I've made an abstract Thread that processes some streams in its run() method. 我制作了一个抽象的Thread,该线程在其run()方法中处理一些流。 I'd like to be able to have the subclasses handle these exceptions rather than the abstract parent class, but I don't know the most elegant way to do that. 我希望能够让子类处理这些异常,而不是抽象的父类,但是我不知道最优雅的方法。 Right now, I'm doing something like this: 现在,我正在做这样的事情:

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 */ }
}

I guess I should mention that the ChildThread is actually an inner class of my main form, and that its logger belongs to that form. 我想我应该提到ChildThread实际上是我主窗体的内部类,并且它的记录器属于该窗体。

Another approach I thought of was to have an 我想到的另一种方法是

abstract void handleException(Exception ex);

in ParentThread, but then I'm not able to handle individual exceptions from the ChildThread. 在ParentThread中,但是后来我无法处理ChildThread中的个别异常。

Well there's no difference between 好吧,两者之间没有区别

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

and

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

although the latter may require some casting. 尽管后者可能需要一些铸造。

Your abstract handleException(Exception ex) idea is sound, I'd go with that. 您的abstract handleException(Exception ex)想法很合理,我同意。 I'd be inclined to not make it abstract , though, and define a sensible default implementation in ParentThread , and allow ChildThread to override it if required. 不过,我倾向于使其abstract ,并在ParentThread定义一个明智的默认实现,并在需要时允许ChildThread覆盖它。

Your first solution seems conceptually wrong to me: mixing application-specific error-handling with generic logging. 您的第一个解决方案在概念上似乎对我来说是错误的:将特定于应用程序的错误处理与常规日志记录混合在一起。

Your second idea (the callback) seems a better solution and offers the possibility of abstracting away the implementation-specific exceptions for custom events, for example: 您的第二个想法(回调)似乎是一个更好的解决方案,并提供了为自定义事件抽象出特定于实现的异常的可能性,例如:

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 {        
}

Why is your base class logging exceptions ? 为什么基类记录了异常? Why not use what the platform provide Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) and let it do whatever instead of mixing logging w/ your do-stuff component. 为什么不使用平台提供的Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)并让它执行任何操作,而不是混合使用do-stuff组件进行日志记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java CountDownLatch.await() 抛出异常“与 Runnable.run() 中的 throws 子句不兼容” - Java CountDownLatch.await() throws Exception "not compatible with throws clause in Runnable.run()" 在JAVA Servlet中将Runnable.run()转换为Callable.call() - Convert Runnable.run() to Callable.call() in JAVA Servlet runnable.run()是不是错了? - Is it wrong to do runnable.run()? 显式调用Runnable.run - Explicit call of Runnable.run 为什么这个程序打印“你好”? (在 Java 中函数指针如何转换为 Runnable.run()) - Why does this program print "Hello"? (how is a function pointer translated to Runnable.run() in Java) 从 SwingWorker 调用 done 方法时是否必须使用 Runnable.run - Is it mandatory to use Runnable.run while calling done method from SwingWorker 如何正确重写Runnable.run(),以便它可以接受参数? - How to properly override Runnable.run(), so it can take parameters? Java错误-Send不是抽象的,并且不会在Runnable中覆盖抽象方法run() - Java error - Send is not abstract and does not override abstract method run() in Runnable 在Runnable中抛出异常 - Throwing exception in runnable Runnable.run InterruptedException 中恢复的中断如何传播到调用方方法? - How does the restored interrupt in a Runnable.run InterruptedException propagate to the caller method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM