这段代码如何重构

有类似这么个代码:
[code="java"]
FTPClient fc = new FTPClient();
try {
fc.connect("127.0.0.1");
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//略去其他
[/code]
在我程序中有类似大量这种try、catch出现,而且每次都要判断一下,如果没有异常就返回true,如果有异常就返回false,同时大多是这种fc.connect("127.0.0.1"),返回的是void类型的,本来想写个方法如:public static boolean xxx(void obj){里面是try、catch和判断},
然后调用如:Test.xxx(fc.connect("127.0.0.1")),然后如果连接成功则返回true,失败则返回false,最后我再根据结果做相应业务处理。
但是参数类型是不能为void的,那么该如何是好啊?如果每次都是try、catch及大量boolean判断,整个代码将相当冗余及逻辑混乱。

其实楼上都说的是异常处理办法,给你一段代码:
[code="java"]
public class DownLoadUtil {

public static FTPClient open(String url, int port, int connectionTimes, int timeOut, String username, String password) throws IOException {
    FTPClient ftp = new FTPClient();
    ftp.setConnectTimeout(timeOut);
    for (int i = 1;; i++) {
        try {
            ftp.connect(url, port);
            ftp.login(username, password);
            return ftp;
        } catch (IOException e) {
            if (i >= connectionTimes) throw e;
        }
    }
}
public static void close(FTPClient ftp) {
    if (ftp != null) {
        try {
            ftp.disconnect();
        } catch (IOException e) {
        }
    }
}
public static void downFile(String url, int port, int connectionTimes, int timeOut, String username,
        String password, String remotePath, String fileName, String localPath) throws IOException {
    FTPClient ftp = null;
    try {
        ftp = open(url, port, connectionTimes, timeOut, username, password);
        ftp.changeWorkingDirectory(remotePath);

        FTPFile[] fs = ftp.listFiles();
        for (FTPFile ff : fs) {
            String path = remotePath + HandleFileNameUtil.handleFileName(fileName);
            // 判断是否是主服务器文件路径
            if (ff.getName().equals(path)) {
                // 经过处理后的文件名
                File localFile = new File(localPath + "/" + HandleFileNameUtil.handleFileName(fileName));
                try (OutputStream is = new FileOutputStream(localFile)) {
                    ftp.retrieveFile(ff.getName(), is);
                }
            }
        }
    } finally {
        close(ftp);
    }
}

}
[/code]

异常上抛

把上面的代码段放到一个方法中,如:
[code="java"]
public static boolean connect(FTPClient fc, String ip) {
try {
fc.connect("127.0.0.1");
return true;
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException npe) {
npe.printStackTrace();
}
return false;
}
[/code]
上面代码块的缺点就是不知道发生了何种异常。建议你自定义一个异常类,然后设置异常编码,把上面可能发生的异常定义成相应的编码,然后抛到上层

如果不想太多catch语句块,你可以向上层抛,然后在最外层根据Exception的种类,进行不同的处理。

public static boolean connect(FTPClient fc, String ip) throws Exception{

fc.connect("127.0.0.1");

交给要调用的地方处理,如果调用的地方,连接都出了异常,就直接不用调用别的方法了

(1)如果出现SocketException,IOException的时候处理都是e.printStackTrace(),那应该就不用分开捕获了异常,没有实际意义;
(2)
Test.xxx(fc.connect("127.0.0.1")),这样写同样需要捕获异常,是不是可以考虑把fc.connect("127.0.0.1")放到Test.xxx方法的声明里,出现异常返回false,无异常返回true;
(3)常是否异往上抛可能决定于你对fc.coct("127.0.nne0.1")的错误处理机制,如果出现这种错误不需要继续运行后续代码,那么可以考虑直接向上抛出,如果向上抛出的异常类型对你的业务逻辑没有意义的话可以在Test.xxx方法中把异常转换为RuntimeException,可能方法的签名会简洁清晰一点。

你这异常抓的一点意义都没有 你可能天天看着后台或者天天看着日志去吗

出现异常要么自行处理掉 要么 抛给上层调用者

针对用户操作层抛出的异常 那么必须给予用户提示

如果你使用的是JDK7,可以考如下建议:

1)如果确实应该捕获这些异常,并且两个异常处理方式都是相同的,可以使用Java7新加入的语法来处理:
catch(SocketException|IOException e) {
//处理代码
}

2)其实实际使用的过程中应该还有另外一个问题,就是需要处理的finally块,
比如
catch(SocketException|IOException e) {
//处理代码
} finally {
if(client!=null) {
client.close();
}
}

这个可以使你FTPClient实现AutoCloseable接口,这样就省去finally里面的麻烦了(finally里面的代码不做的话,有可能会造成连接泄露)。这个也是Java7里面的功能。

可以把异常抛出去,在上一层调用时,统一处理
这样做就是不知道具体是那个处理上抛出了异常,提示信息不好打...