2011-04-25 31 views
3

我想從傳入的值(使用Bundle)在Android中創建一個IP地址,如果失敗,我使用硬編碼的默認IP地址創建它。如果失敗,我退出應用程序。在Java中嵌套try/catch語句是否可接受?

我想知道的是,如果它可以像我在這裏做的那樣嵌套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(); 
    } 
} 
+1

我會寫完全像這樣,包括評論 – 2011-04-25 02:00:44

回答

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

感謝克里斯,這看起來像一個很好的整潔的方式來做到這一點,如果我進入更多的層築巢。乾杯,史蒂夫 – Steve 2011-04-25 02:06:04

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

我認爲這將是值得商榷什麼樣的方式更好,但這裏的另一種選擇,有些人可能認爲是一個有點「表現」和可讀性,雖然它是多行代碼:

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(); 
+0

同意,這是相當有爭議的。但我非常喜歡所有提議的選項。 – 2011-04-25 02:01:17

+0

我也喜歡這種方式,但我認爲Chris的選擇整體看起來更整潔。它很好地知道有一堆不同的可接受的方式來做到這一點 – Steve 2011-04-25 02:09:52

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(); 
    } 
} 
+0

當然,如果你在catch語句中,那麼我們知道地址== null?因此,添加'如果'只是額外的不必要的代碼?我認爲嵌套的想法可能更加整潔 - 我只關心它的可接受性......乾杯,史蒂夫 – Steve 2011-04-25 02:20:34

+0

是的,他們都工作得很好,但大多數人發現它更易讀,以避免嵌套異常。 – Haphazard 2011-04-25 02:29:00

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值調用失敗,則異常ip地址之前拋出被修改,所以ip地址已設置爲默認。當然,如果DEFAULT_IP應該總是可以解析的,這只是一個有效的模式。

+0

這是一個很好的簡單選項 - 但不幸的是,DEFAULT_IP可能無法解析......它更多的用於測試我的環境(它將在哪裏解析),但在現實世界中它可能不會。乾杯,史蒂夫 – Steve 2011-04-25 02:23:46

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循環匹配3 -party日期字符串)