2015-04-05 50 views
0

例如:Java:是否可以縮短try/catch?

try { 
     Thread.sleep(333); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

我可以用某種方式上面的try/catch使用像trySleep(Thread.sleep(333));創建的方法會做同樣的原始試試?

使用的例子:

public class Test implements Runnable { 

    public Test() { 
     Thread thisThread = new Thread(this); 
     thisThread.start(); 
    } 

    @Override 
    public void run() { 
     while (true){ 
      System.out.println("Testing"); 
      trySleep(Thread.sleep(333)); 
     } 
    } 

    public void trySleep(/*Thread object*/){ 
     //Code for try/catch 
    } 

    public static void main(String[] args) { 
     new Test(); 
    } 

} 

當然上面的代碼將無法編譯,它只是一個問題。

我想要這種事情的原因是因爲我覺得try/catch的東西太混亂了,並且很煩人。

+0

你是什麼原因不內聯這個聲明? – 2015-04-05 23:06:31

回答

2

你可以在重新拋出任何異常的運行時異常(或任何未捕獲的異常)的函數包裝Thread.sleep

public static void trySleep(long millis) { 
    try { 
     Thread.sleep(millis); 
    } catch (InterruptedException e) { 
     throw new RuntimeException("Interrupted during sleep", e); 
    } 
} 
+0

我一直認爲Thread.sleep必須在它運行的線程中?如果你在construtor'Test()'中調用它,它將不起作用。 – FOD 2015-04-05 23:07:02

+2

@FOD當你從'run'裏面調用'trySleep'時,你會在當前線程中調用它。功能定義在哪裏並不重要。 – axblount 2015-04-05 23:08:50

1

我不明白這個問題。如果將三行添加到trySleep方法體中,您將得到一個方法,該方法將讓線程休眠。

所以答案是肯定的。

順便說一句: 您寫了無盡的睡眠循環

+0

我知道這是無止境的,這只是我選擇的一個快速示例,示例中的其他任何內容都是毫無意義和無關緊要的。 – FOD 2015-04-05 23:07:59

+0

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 – 2015-04-06 04:16:13

+1

@HarshalPatil:有關「如果將三行添加到trySleep方法」的部分就是答案。我在這個問題上遇到了一些問題,因爲問題中包含了答案。 – 2015-04-06 18:06:43

1

是的,你可以做到這一點,但不完全是你現在描述的方式。無論你使用Thread.sleep()你必須抓住InterruptedException,所以你必須附上電話在這樣的方法:

public void trySleep(long ms) { 
    try { 
     Thread.sleep(ms); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); //handle exception here 
    } 
} 

您可以調用此方法是這樣的:trySleep(333)

有時更好只是爲你的方法添加一個throws聲明或重新拋出一個更有意義的異常,除非你知道這是捕獲異常最有意義的位置。

0

您可以在您擁有的另一種方法中將您的睡眠代碼換行。

public static void trySleep(Thread target, long millis){ 
    try{ 
     target.sleep(millis); 
    } catch(InterruptedException e) { 
     System.err.println("Exception Occurred while trying to sleep!"); 
    } 
} 

您可能應該這樣做,事實上,因爲使代碼模塊化是正確的方式。

+0

由於[Thread.sleep(...)'](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#「target」參數是多餘的和誤導性的sleep%28long%29)是導致_current_線程休眠的靜態方法。爲了可讀性,靜態方法不應該通過實例引用來調用。 – 2015-04-05 23:47:11

0

我認爲你真的需要考慮的一件重要事情(除了如何正確執行此操作的答案之外),是瞭解你所調用的代碼。

在您的代碼:

@Override 
public void run() { 
    while (true){ 
     System.out.println("Testing"); 
     trySleep(Thread.sleep(333)); 
    } 
} 

特別是這一行:

trySleep(Thread.sleep(333)); 

你基本上說

  • 與值調用該方法的Thread.sleep() 333.

  • 無論Thread.sleep()返回什麼值,都將其傳遞給另一個方法。

the Javadocs說這是一個無效的方法。

而且在你的代碼:

public void trySleep(/*Thread object*/){ 
    //Code for try/catch 
} 

您應該檢查this stackoverflow post了爲什麼這是不好的做法(如你會嘗試調用靜態方法的實例對象)。

其他人已經回答了您的問題,但我強烈建議您對這些問題進行研究,因爲這表明您可能會遺漏某些重要概念的重要知識。

0

您可以使用Java 8的Lambda表達式做類似這樣的東西:

@FunctionalInterface 
interface InterruptedExceptionRunnable { 
    void run() throws InterruptedException; 
} 

void trySleep(InterruptedExceptionRunnable exRunnable) { 
    try { 
     exRunnable.run(); 
    } catch(InterruptedException ex) { 
     ex.printStackTrace(); 
    } 
} 

它允許你這樣寫:與Java 8 Lambda表達式

trySleep(()->Thread.sleep(333)); 
0

是的,你可以做的基本上是這樣的。

class Example { 
    @FunctionalInterface 
    interface InterruptableRunnable { 
     void run() throws InterruptedException; 
    } 

    static void tryRun(InterruptableRunnable r) { 
     try { 
      r.run(); 
     } catch(InterruptedException ie) { 
      ie.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     Thread t = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       // passing a lambda 
       tryRun(() -> Thread.sleep(333)); 
      } 
     }); 

     t.start(); 
     // passing a method reference 
     tryRun(t::join); 
    } 
}