【问题标题】:Rethrow different caught exceptions in java在java中重新抛出不同的捕获异常
【发布时间】:2013-04-14 15:41:06
【问题描述】:

我有以下下载功能。我在途中捕获了一些可能的异常,并将它们存储在 Exception 类型变量中,在 finally 块中清理后,我想重新抛出原始异常(如果有一个被捕获)或抛出我自己的自定义 DownloadFailedException .问题是 Eclipse 给了我“未处理的异常类型异常”错误,因为我的函数没有声明抛出异常。有没有“好”的方法来做到这一点?

public static boolean downloadFile(String urlString, String dstPath) throws DownloadFailedException, IOException {
    if (!Settings.isNetworkAvailable()) {
        throw new NoNetworkException("Network error: no internet connection. Failed downloading " + urlString);
    }
    InputStream input = null;
    BufferedOutputStream output = null;
    int fileLength = -1;
    long total = 0;
    int statusCode = -1;
    HttpGet get = new HttpGet(urlString);
    get.setHeader("User-Agent", Settings.getUserAgent());
    get.setHeader("X-My-Id", Settings.getDeviceId());
    HttpClient client = new DefaultHttpClient();
    HttpResponse response = null;
    try {
        response = client.execute(get);
        statusCode = response.getStatusLine().getStatusCode();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (200 != statusCode) {
            throw new DownloadFailedException("http error: " + statusCode +". Failed downloading " + urlString, statusCode);
        }
    }
    if (null != response) {
        HttpEntity entity = response.getEntity();
        File tmpFile = null;
        Exception exception = null;
        try {
            InputStream is = entity.getContent();
            byte b[] = new byte[1];
            is.read(b, 0, 0);
            fileLength = (int)entity.getContentLength();
            input = new BufferedInputStream(is, 8192);
            tmpFile = new File(dstPath + ".tmp");
            tmpFile.createNewFile();
            output = new BufferedOutputStream(new FileOutputStream(tmpFile), 8192);

            byte data[] = new byte[8192];
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                output.write(data, 0, count);
            }
        } catch (IllegalStateException e) {
            exception = e;
            e.printStackTrace();
        } catch (IOException e) {
            exception = e;
            e.printStackTrace();
        } finally {
            try {
                if (null != output) {
                    output.flush();
                    output.close();
                }
                if (null != input)
                    input.close();
            } catch (IOException e) {
                if (null == exception)
                    exception = e;
            }
            if (-1 < fileLength && total != fileLength) {
                if (null != tmpFile) {
                    tmpFile.delete();
                }
                if (null != exception) {
// HERE I WOULD LIKE TO RE-THROW THE ORIGINAl EXCEPTION
                    throw exception; // Unhandled exception type Exception
                    //also tried: exception.getClass().cast(exception);
                } else
                    throw new DownloadFailedException(urlString + ": only " + total + " bytes read out of " + fileLength);
            }
            File dstFile = new File(dstPath);
            tmpFile.renameTo(dstFile);
        }
        return true;
    }
    return false;
}

解决方案:

if (null != exception) {
    if (exception instanceof IllegalStateException)
        throw (IllegalStateException) exception;
    else if (exception instanceof IOException)
        throw (IOException) exception;
    else
        throw new RuntimeException(message, exception);
}
//throw new IOException("Only " + total + "bytes read from " + fileLength);
throw new DownloadFailedException(message);

【问题讨论】:

    标签: java exception throw throws rethrow


    【解决方案1】:

    你在哪里:

    // HERE I WOULD LIKE TO RE-THROW THE ORIGINAl EXCEPTION
    throw exception; // Unhandled exception type Exception
    // also tried: exception.getClass().cast(exception);
    

    我会用这个:

    if(exception instanceof IOException)
        throw (IOException) exception;
    else
        throw new DownloadException(exception);
    

    根据您描述的情况和方法末尾的throws 子句,该代码可以执行您想要执行的操作。在英语中,代码的作用如下:

    • 如果你捕捉到一个Exception 并且它是一个IOException,那么你想抛出一个IOException
    • 如果您发现Exception 而不是IOException,您想抛出DownloadException(您自己创建的)。我们将任何非IOException 包装在DownloadException 中,以便您的实现与您方法中的throws 子句保持一致。
    • 如果您没有收到Exception,那么您希望生活照常进行

    请注意,在编译之前,您可能需要将 public DownloadException(Throwable e){super(e);} 之类的构造函数添加到您的类 DownloadException(如果具有该签名的构造函数尚不存在)。

    【讨论】:

    • 我会尝试,虽然我需要添加一个“else if (exception instanceof IllegalStateException)..”,因为这是一个 RuntimeException(我认为它被称为 unchecked,这就是为什么它不在函数的 throws 声明)
    • 这是有道理的。抱歉,不是从上面挑出来的。除了测试IllegalArgumentException,您还可以测试RuntimeExceptionthrow 匹配的任何内容(转换为RuntimeException)。
    猜你喜欢
    • 2011-06-27
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 2021-04-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多