このトライアンドキャッチが機能しない理由を誰かに教えてもらえますか?期待するメッセージを出力する代わりに、スキャナー例外をスローします。
import Java.util.*;
import Java.io.*;
import Java.math.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
Boolean test = true;
while (test == true) {
try {
double x, y;
String operator;
Scanner scan = new Scanner(System.in);
Scanner scan_2 = new Scanner(System.in);
Scanner ScanOperator = new Scanner(System.in);
System.out.println(" Enter a double value: ");
x = scan.nextDouble();
System.out.println(" Enter another double value: ");
y = scan_2.nextDouble();
System.out.println(" Enter a operator for the operation you want to execute, or X if you want to quit: ");
operator = ScanOperator.nextLine();
if (operator.equals("x") || operator.equals("X")) {
test = false;
System.out.println("No calculation was made!!!");
}
System.out.println(Calculation(operator, x, y));
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null,"Input must be a number.");
}
}
}
public static double Calculation(String operator, double x, double y) {
double result = 0;
double myAdd = 0;
double mySub = 0;
double myMult = 0;
double myDiv = 0;
double myPower = 0;
double myMod = 0;
if (operator.equals("+")) {
myAdd = x + y;
result = myAdd;
} else if (operator.equals("-")) {
mySub = x - y;
result = mySub;
} else if (operator.equals("*")) {
myMult = x * y;
result = myMult;
} else if (operator.equals("/")) {
myDiv = x / y;
result = myDiv;
} else if (operator.equals("^")) {
myPower = Math.pow(x, y);
result = myPower;
} else if (operator.equals("%")) {
myMod = x % y;
result = myMod;
} else {
}
return result;
}
}
単純なプログラムはScannerExceptionをスローしますが、try catchはNumberFormatExceptionしかキャッチできません。ScannerExceptionをキャッチするために別のcatch句を追加するか、一般的なExceptionのみをキャッチする必要があります。
たとえば、次のように言います。
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null,"Input must be a number.");
}
これは、NumberFormatExceptionをキャッチする方法を指定するだけです。
すべての例外をキャッチするには、次のようにする必要があります。
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null,"Input must be a number.");
}catch (Exception e){
JOptionPane.showMessageDialog(null,"Generic exception caught");
}
この場合、すべての例外がExceptionクラスを拡張するため、2番目のキャッチは最初のキャッチでキャッチされなかったすべてのものを取得します。そのステートメントですべての派生クラスをキャッチできます。
ただし、例外をキャッチすること自体は嫌われているため、次のこともできます。
} catch (NumberFormatException, ScannerException e) {
JOptionPane.showMessageDialog(null,"Input must be a number.");
}
同じブロックで両方の例外をキャッチします。
NumberFormatExceptionをキャッチしようとしています。 NumberFormatExceptionとは異なるため、ScannerExceptionのcatchステートメントを追加する必要があります。
ScannerExceptionまたはこのようなものをキャッチする必要があります。
このコードでは、NumberFormatExceptionのみをキャッチしています。
このようなものを試してください:
try {
...
} catch (NumberFormatException, ScannerException exception) {
JOptionPane.showMessageDialog(null,"Input must be a number.");
}
間違った例外をキャッチしています。
コードはNumberFormatException
をスローしません。代わりにInputMismatchException
をキャッチする必要があります。
nextDouble
をScanner
で見ると、Scanner
コードがNumberFormatException
を処理し、別のタイプの例外をスローしているようです。
Java.util.Scanner
から:
public double nextDouble() {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Double)) {
double val = ((Double)typeCache).doubleValue();
useTypeCache();
return val;
}
setRadix(10);
clearCaches();
// Search for next float
try {
return Double.parseDouble(processFloatToken(next(floatPattern())));
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
このような問題が発生した場合は、最初にJavaソースを確認することをお勧めします。これはすばらしいリソースです。
また、JDKにはScannerException
がないことにも注意してください。
InputMismatchException
の代わりにNumberFormatException
をキャッチするだけで、すべてが正常に機能します。
なぜそうしないのですか?
String input = scan.nextLine();
if(!input.matches("\\d+")) { // regex for 1 or more digits
System.err.println("Input must be at least 1 digit!");
continue; // goes back to the top of the loop
}
double dbl = Double.valueOf(input);
参考までに、倍精度の実際の正規表現は[digit] [。] [digit]であり、[。] [digit]はオプションです。