私の日々のWebアプリケーション開発では、ユーザーからいくつかの入力を行う必要がある多くのインスタンスがあります。
次に、この番号の入力を、アプリケーションのサービス層またはDAO層に渡します。
その数(整数または浮動小数点数)以降のある段階で、次のコードスニペットに示すように、整数に変換する必要があります。
String cost = request.getParameter("cost");
if (cost !=null && !"".equals(cost) ){
Integer intCost = Integer.parseInt(cost);
List<Book> books = bookService . findBooksCheaperThan(intCost);
}
ここで上記のケースでは、入力がnullでないか、入力がない(空白)か、または非数値入力の可能性があるかどうかを確認する必要があります。何とか、テストなど。
そのような状況に対処する最善の方法は何ですか?
例外をキャッチして、適切な例外処理を行うだけです。
if (cost !=null && !"".equals(cost) ){
try {
Integer intCost = Integer.parseInt(cost);
List<Book> books = bookService . findBooksCheaperThan(intCost);
} catch (NumberFormatException e) {
System.out.println("This is not a number");
System.out.println(e.getMessage());
}
}
いつものように、ジャカルタコモンズには少なくとも答えの一部があります。
これは、指定された文字列が数値であるかどうかをほとんどチェックするために使用できます。文字列が数字ではない場合の対処方法を選択する必要があります...
Javaの最近のバージョンでの例外は、回避を重要にするほど高価ではありません。プロセスで早い段階で(つまり、直後に)ユーザーが入力した)、プロセスの後半で問題が発生することはありません(とにかく正しいタイプになるためです)。
例外は、以前よりもはるかに高価になりました。例外が実際に問題を引き起こしていることがわかるまで、パフォーマンスを最適化しないでください(ここではそうしません)。
2つのことを行うことをお勧めします。
public class Main {
public static void main(String[] args) {
String number;
while(true){
try{
number = JOptionPane.showInputDialog(null);
if( Main.isNumber(number) )
break;
}catch(NumberFormatException e){
System.out.println(e.getMessage());
}
}
System.out.println("Your number is " + number);
}
public static boolean isNumber(Object o){
boolean isNumber = true;
for( byte b : o.toString().getBytes() ){
char c = (char)b;
if(!Character.isDigit(c))
isNumber = false;
}
return isNumber;
}
}
1つの可能性:例外をキャッチし、ユーザーフロントエンド内にエラーメッセージを表示します。
編集:GUI内のフィールドにリスナーを追加し、そこのユーザー入力も確認してください。このソリューションでは、例外ケースは非常にまれです...
Apache Commons Langのメソッドに関するドキュメント( from here ):
文字列が有効なJava number。
有効な数字には、0x修飾子でマークされた16進数、科学表記法、および型修飾子でマークされた数字(例:123L)が含まれます。
Null
および空の文字列はfalse
を返します。パラメータ:
`str` - the `String` to check
戻り値:
`true` if the string is a correctly formatted number
isNumber
from Java.org.Apache.commons.lang3.math.NumberUtils :
public static boolean isNumber(final String str) {
if (StringUtils.isEmpty(str)) {
return false;
}
final char[] chars = str.toCharArray();
int sz = chars.length;
boolean hasExp = false;
boolean hasDecPoint = false;
boolean allowSigns = false;
boolean foundDigit = false;
// deal with any possible sign up front
final int start = (chars[0] == '-') ? 1 : 0;
if (sz > start + 1 && chars[start] == '0' && chars[start + 1] == 'x') {
int i = start + 2;
if (i == sz) {
return false; // str == "0x"
}
// checking hex (it can't be anything else)
for (; i < chars.length; i++) {
if ((chars[i] < '0' || chars[i] > '9')
&& (chars[i] < 'a' || chars[i] > 'f')
&& (chars[i] < 'A' || chars[i] > 'F')) {
return false;
}
}
return true;
}
sz--; // don't want to loop to the last char, check it afterwords
// for type qualifiers
int i = start;
// loop to the next to last char or to the last char if we need another digit to
// make a valid number (e.g. chars[0..5] = "1234E")
while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
if (chars[i] >= '0' && chars[i] <= '9') {
foundDigit = true;
allowSigns = false;
} else if (chars[i] == '.') {
if (hasDecPoint || hasExp) {
// two decimal points or dec in exponent
return false;
}
hasDecPoint = true;
} else if (chars[i] == 'e' || chars[i] == 'E') {
// we've already taken care of hex.
if (hasExp) {
// two E's
return false;
}
if (!foundDigit) {
return false;
}
hasExp = true;
allowSigns = true;
} else if (chars[i] == '+' || chars[i] == '-') {
if (!allowSigns) {
return false;
}
allowSigns = false;
foundDigit = false; // we need a digit after the E
} else {
return false;
}
i++;
}
if (i < chars.length) {
if (chars[i] >= '0' && chars[i] <= '9') {
// no type qualifier, OK
return true;
}
if (chars[i] == 'e' || chars[i] == 'E') {
// can't have an E at the last byte
return false;
}
if (chars[i] == '.') {
if (hasDecPoint || hasExp) {
// two decimal points or dec in exponent
return false;
}
// single trailing decimal point after non-exponent is ok
return foundDigit;
}
if (!allowSigns
&& (chars[i] == 'd'
|| chars[i] == 'D'
|| chars[i] == 'f'
|| chars[i] == 'F')) {
return foundDigit;
}
if (chars[i] == 'l'
|| chars[i] == 'L') {
// not allowing L with an exponent or decimal point
return foundDigit && !hasExp && !hasDecPoint;
}
// last character is illegal
return false;
}
// allowSigns is true iff the val ends in 'E'
// found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
return !allowSigns && foundDigit;
}
[コードはApacheライセンスのバージョン2の下にあります]
Prizeを10進形式に変換してみてください...
import Java.math.BigDecimal;
import Java.math.RoundingMode;
public class Bigdecimal {
public static boolean isEmpty (String st) {
return st == null || st.length() < 1;
}
public static BigDecimal bigDecimalFormat(String Preis){
//MathContext mi = new MathContext(2);
BigDecimal bd = new BigDecimal(0.00);
bd = new BigDecimal(Preis);
return bd.setScale(2, RoundingMode.HALF_UP);
}
public static void main(String[] args) {
String cost = "12.12";
if (!isEmpty(cost) ){
try {
BigDecimal intCost = bigDecimalFormat(cost);
System.out.println(intCost);
List<Book> books = bookService.findBooksCheaperThan(intCost);
} catch (NumberFormatException e) {
System.out.println("This is not a number");
System.out.println(e.getMessage());
}
}
}
}
文字列がIntまたはFloatであるかどうかを判断し、より長い形式で表すには
整数
String cost=Long.MAX_VALUE+"";
if (isNumeric (cost)) // returns false for non numeric
{
BigInteger bi = new BigInteger(cost);
}
public static boolean isNumeric(String str)
{
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
Scannerクラスを使用すると、不愉快に見えるtry/catchまたはregexを回避できます。
String input = "123";
Scanner sc = new Scanner(input);
if (sc.hasNextInt())
System.out.println("an int: " + sc.nextInt());
else {
//handle the bad input
}