我正在尝试从传入的值(使用Bundle)在Android中创建IP地址,如果失败,我将使用硬编码的默认IP地址创建它。如果失败则我退出应用程序。
我想知道的是,如果可以像我在这里做的那样嵌套try / catch,或者是否有更好的方法。
try {
// serverSettings is the Bundle name that was passed in.
ipAddress = InetAddress.getByName(serverSettings.getString("serverIp"));
} catch (UnknownHostException e) {
Log.e("ERROR:", "IOException: Failed to create IP, trying default");
try {
// DEFAULT_IP is the hard-coded default fall-back address
ipAddress = InetAddress.getByName(DEFAULT_IP);
} catch (UnknownHostException e1) {
Log.e("ERROR:", "IOException: Total fail, exiting");
e1.printStackTrace();
finish();
}
}
答案 0 :(得分:9)
这是合法的Java。它看起来很笨重,我可能会采用不同的方式,但它有效且有效。
我是这样做的:
public InetAddress getServerAddress() {
for (String address : new String[] {serverSettings.getString("serverIp"), DEFAULT_IP}) {
try {
return InetAddress.getByName(address);
} catch (UnknownHostException e) {
Log.e("ERROR:", "Cannot resolve " + address);
}
}
Log.e("ERROR:", "Total fail, exiting");
finish();
return null; // not reached
}
答案 1 :(得分:4)
我认为哪种方式更好会有争议,但这是另一种选择,有些人可能会认为它更具“表现力”和可读性,尽管它的代码更多:
public InetAddress tryHost(String hostName) {
InetAddress address = null;
try {
address = InetAddress.getByName(hostName);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}
然后在您的代码中,执行:
InetAddress address = null;
address = tryHost(serverSettings.getString("serverIp"));
if (address = null)
address = tryHost(DEFAULT_IP);
if (address = null) {
// handle error, throw exception
}
finish();
答案 2 :(得分:2)
另一种变体是首先设置默认值:
ipAddress = null;
try {
// serverSettings is the Bundle name that was passed in.
ipAddress = InetAddress.getByName(DEFAULT_IP); // Set default address
ipAddress = InetAddress.getByName(serverSettings.getString("serverIp")); // Try passed-in address
} catch (UnknownHostException e) {
if (ipAddress == null) {
Log.e("ERROR:", "IOException: Total fail, exiting");
e1.printStackTrace();
finish();
}
}
如果使用Bundle'd值的调用失败,则在修改ipAddress之前抛出异常,因此ipAddress已设置为默认值。当然,如果DEFAULT_IP应该始终可以解析,这只是一个有效的模式。
答案 3 :(得分:1)
没关系。您还可以使用在第一个catch中打开的布尔标志,因此如果您的布尔标志已打开,则在catch外部通过IP执行请求。
boolean failed = false;
try {
// serverSettings is the Bundle name that was passed in.
ipAddress = InetAddress.getByName(serverSettings.getString("serverIp"));
} catch (UnknownHostException e) {
failed = true;
Log.e("ERROR:", "IOException: Failed to create IP, trying default");
}
if(failed){
try {
// DEFAULT_IP is the hard-coded default fall-back address
ipAddress = InetAddress.getByName(DEFAULT_IP);
} catch (UnknownHostException e1) {
Log.e("ERROR:", "IOException: Total fail, exiting");
e1.printStackTrace();
finish();
}
}
}
答案 4 :(得分:1)
我更喜欢这个。它有点清洁,不涉及额外的标志。
InetAddress ipAddress = null;
try {
// serverSettings is the Bundle name that was passed in.
ipAddress = InetAddress.getByName(serverSettings.getString("serverIp"));
} catch (UnknownHostException e) {
Log.e("ERROR:", "IOException: Failed to create IP, trying default");
}
if(ipAddress==null){
try {
// DEFAULT_IP is the hard-coded default fall-back address
ipAddress = InetAddress.getByName(DEFAULT_IP);
} catch (UnknownHostException e1) {
Log.e("ERROR:", "IOException: Total fail, exiting");
e1.printStackTrace();
finish();
}
}
答案 5 :(得分:0)
在进行更大规模的测试(首先获胜)时,我喜欢的另一种变体:
ipAddress = null;
// serverSettings is the Bundle name that was passed in.
String[] addresses = { DEFAULT_IP,
serverSettings.getString("serverIp") };
int i = 0;
do {
try {
ipAddress = InetAddress.getByName(addresses[i]);
} catch (UnknownHostException e) {
Log.e("ERROR:", "IOException: Failed to create IP, trying next");
}
} while (ipAddress == null && i < addresses.length);
if (ipAddress == null) {
Log.e("ERROR:", "IOException: Total fail, exiting");
e1.printStackTrace();
finish();
}
这可能更适合我的正常用例(循环使用SimpleDateFormats来匹配第三方日期字符串)