2016-12-07 27 views
1

I Javaコードの以下のビットがあります避けネストされたのtry-catchブロック

SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH"); 
Date date; 
try { 
    date = df.parse(userString); 
} catch (ParseException e) { 
    date = df.parse("07/12/2016 01:00"); 
    LOGGER.error("Could not parse date, reverting to default"); 
} 

そうで、私がやろうとしていることはそれが失敗した場合に、日付などのユーザー入力を解析することですそれをデフォルトの日付に置き換えます。

しかし、2番目のdf.parse()には、それ自身のtry-catchが必要ですが、それは確かに私が知っている価値です。それは第二のparseが働かないことには意味をなさないが、もし本当にそうしなければ、私はこれ以上何もしない。世界が終わったのでプログラムを終了するかもしれない。 :)

try-catchブロックの必要性を避ける方法はありますか?

答えて

2

2回目の試合をするのは意味がないと言います。これは真実ですはい、あなたは失敗するつもりはないが、Javaはこれを知らないと言っています。

デフォルトの日付参照を1つ前に解析し、ストアをクラスメンバーとして返してもかまいません(ただし、それでもtry catchが必要です - それは不変ではありません)。

コード行を減らそうとしても問題はありません。この質問にはいくつかの答えがありますが、これはtry-catchを回避するための回避策ですが、これらはコードをあまり明確でなく、エラーを起こしやすいと思います。など

私はちょうどこのような場合には、ネストされたのtry-catchを使用して、あなたの生活に移動する変数を再割り当てしていない、状態フラグを避けるNULL値可能な値を避けるために思考の学校があります。それは他のアプローチよりも少し、しかし醜いですが、より安全で明瞭です。私が質問に答えることはあなたのコードを悪化全体的になり思うので

だから、これはあなたの質問への答えではありませんが、私はこれを掲示していますがその答えです。 :)

これは...私は最高の可読性、保守性および安全性のための機能を記述します方法です

public Date parseDate(String userString) { 
    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH"); 
    try { 
     return df.parse(userString); 
    } catch (ParseException e) { 
     LOGGER.error("Could not parse date '" + userString + "' reverting to default"); 
     try { 
      return df.parse("07/12/2016 01:00"); 
     } catch (ParseException shouldntHappen) { 
      throw new RuntimeException(shouldntHappen); 
     } 
    } 
} 
1

ParseExceptiontrueisErrorフラグをチェックしてfinallyブロックでのデフォルトの日付を設定することにより、以下のようにあなたは、ネストされたtryを避けることができます。

SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH"); 
    Date date1; 
    Date date2; 
    boolean isError = false; 
    try { 
     date1 = df.parse("07/12/2016 01:00"); 
     date2 = df.parse(userString); 
    } catch (ParseException e) { 
     isError= true; 
     LOGGER.error("Could not parse date, reverting to default"); 
    } finally { 
     if(isError) { 
      date2 = date1; 
     } 
    } 
+0

downvoters、私は訂正またはそれから何かを学ぶことができるように、この方法の問題点をコメントしてください – developer

+0

私は投票した人でした。さて、まずisErrorチェックを行う必要はありません。好き。 'try {date = df.parse(defaultString); date = df.parse(userString); } '' defaultString'は解析に失敗しますので、 'userString'が失敗した場合でもデフォルトの日付を持ち、' ​​isError'を扱う必要はありません。あなたの方法が間違っているとは言いませんが、特に多くのことをするには、例外をスローしない 'SimpleDateFormat.parse(String text、ParsePosition pos)'メソッドがあります。 – Onur

+0

パフォーマンスについての質問であれば、とにかく、あなたの意見を得ました。 – developer

0

私はメソッドにこの機能を移動するだろうし、することができます再利用する

public static void main (String [] args) 
{ 

    Date dt = setDate ("07/12/2016 x1:00"); 
    if (dt == null) { 
     dt = setDate ("07/12/2016 01:00"); 
    } 

    System.out.println(dt); 
} 

private static Date setDate(String in) { 

    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH"); 
    Date date = null; 
    try { 
     date = df.parse(in); 
    } catch (ParseException e) { 
     System.out.println("Could not parse date, reverting to default"); 
    }  

    return date; 
} 
+0

これはとても良い考えです。少しの追加として、関数内にあるということは、両方のエラーメッセージが同じであることを意味します。だから、誰が誰であるかを知るために、エラーメッセージのパラメータを広告しなければなりません。そうでなければ、デバッグ時に、メッセージ(あなたが知っている、世界が終わり、2番目の解析がエラーを投げた場合に備えて) – evilpenguin

-1

ParseExceptionがチェックされている例外です。だからあなたはブロックをキャッチするか、メソッドの宣言でそれを書くだけで、PraseExceptionをスローする必要があります。しかし、あなたの呼び出しメソッドは、例外をキャッチする必要があります。 あなたはそれを解析する必要がない場合は、あなただけ使うことができることを意味し、あなたのデフォルトの日付が予め定められている場合はチェック例外

1

を回避するための他の方法はありません

date = new Date(1468285200L * 1000); // unix time * 1000(milliseconds) 

それ以外の場合はちょうどこのようSimpleDateFormat.parse(String text, ParsePosition pos)を使用します。任意のParseExceptionを投げるが、構文解析が成功したかどうかに基づいて、日付やnullを返していない

date = df.parse("07/12/2016 01:00", new ParsePosition(0)); 

0

特定の日付を作成するための正しい方法は、既存の日時のクラスである:

LocalDateTime local = LocalDateTime.of(2016, 7, 12, 1, 0); 
ZonedDateTime zoned = ZonedDateTime.of(local, ZoneId.systemDefault()); 
date = Date.from(zoned.toInstant()); 

ます。また、カレンダーを使用することができます。あなたは、JavaのバージョンのJava 8よりも古いを使用している場合は、カレンダーがそれを行うための唯一の方法である:

Calendar calendar = Calendar.getInstance(); 
calendar.set(2016, Calendar.JULY, 12, 1, 0, 0); 
date = calendar.getTime(); 

は注意:Calendar.JULYは、エラーを回避するために、月の定数を使用し7に等しくありません。

関連する問題