封装Integer.parseInt()的好方法


88

我有一个项目,我们经常在其中Integer.parseInt()将String转换为int。当出现问题时(例如,String不是数字,而是字母a或其他),此方法将引发异常。但是,如果我到处都必须处理代码中的异常,这很快就会非常难看。我想将其放在一个方法中,但是,我不知道如何返回一个干净的值以表明转换出错。

在C ++中,我可以创建一个方法,该方法接受一个指向int的指针,并让该方法本身返回true或false。但是,据我所知,这在Java中是不可能的。我也可以创建一个包含true / false变量和转换后的值的对象,但这似乎也不理想。全局值也一样,这可能会给我带来多线程问题。

那么有没有一种干净的方法可以做到这一点?


字符串中的字符必须全部为十进制数字,但第一个字符...除外。无需在代码中各处处理异常,只需在调用parse方法之前检查字符串格式即可。
莱特曼

几乎不可能编写一个正则表达式来捕获所有有效的32位带符号整数,而没有一个无效整数。2147483647是合法的,int而2147483648不是。
塞瓦·阿列克谢耶夫

Answers:


139

您可以返回Integer而不是,以在解析失败时int返回null

遗憾的是,Java没有提供一种没有内部抛出异常的方法来执行此操作-您可以隐藏该异常(通过捕获该异常并返回null),但是如果您要解析数百个异常,它仍然可能是性能问题用户提供的数以千计的数据。

编辑:这种方法的代码:

public static Integer tryParse(String text) {
  try {
    return Integer.parseInt(text);
  } catch (NumberFormatException e) {
    return null;
  }
}

请注意,如果不确定text为null ,我不确定该怎么办。您应该考虑-如果它代表一个错误(即您的代码很可能传递了一个无效值,但绝不应该传递null),则抛出异常是适当的;如果它不代表错误,那么您可能应该返回null,就像返回其他任何无效值一样。

最初,这个答案使用了new Integer(String)构造函数。现在使用Integer.parseInt和拳击操作;这样,小的值最终将被装箱到缓存的Integer对象中,从而使其在那些情况下更加有效。


1
这有什么帮助?呼叫站点将要求:<b> temp = tryParse(...); 如果(temp!= Null){target = temp; } else {做恢复动作}; </ b>在恢复部分可能抛出异常。在原始公式中,呼叫站点需要<b> try target =(...)。parseInt; catch(...){执行恢复操作} </ b>,只需删除catch子句,即可在恢复中实现一个简单的异常抛出。所提出的解决方案如何使它更易于理解(有魔术)或以任何方式减少代码量?
Ira Baxter,2009年

14
通常,编写代码来检查null引用要比定期处理异常更干净。
亚当·马拉斯

避免将null作为值传递甚至更干净,而是以某种方式表明发生了错误。异常不应用于流控制。
Esko

2
@Steve Kuo:为什么?好处在哪里?他们每次都创建一个新的Integer吗?如果有的话,我很想使用Integer.parseInt并让自动装箱处理它,以利用高速缓存中的小值。
乔恩·斯基特

1
@Vlasec不仅是Optional,而且是原语的专用版本,例如OptionalInt。
约书亚·泰勒

36

如果不是数字,您会期望什么行为?

例如,如果在输入非数字的情况下经常使用默认值,则可以使用如下所示的方法:

public static int parseWithDefault(String number, int defaultVal) {
  try {
    return Integer.parseInt(number);
  } catch (NumberFormatException e) {
    return defaultVal;
  }
}

无法解析输入时,可以针对不同的默认行为编写类似的方法。


29

在某些情况下,您应该将解析错误视为快速失败的情况,但是在其他情况下,例如应用程序配置,我更喜欢使用Apache Commons Lang 3 NumberUtils处理具有默认值的缺失输入。

int port = NumberUtils.toInt(properties.getProperty("port"), 8080);

大多数时候,由于其他原因(例如StringUtils),您已经在项目中使用apache commons变得很方便。
Ratata Tata

17

为了避免处理异常,请使用正则表达式来确保您将所有数字都放在首位:

//Checking for Regular expression that matches digits
if(value.matches("\\d+")) {
     Integer.parseInt(value);
}

谢谢您的回答。我通读了本页上的大多数答案,我亲自编写了try / catch解决方案。但是,这是我的问题,尽管解决方案很小。当您在一个循环内进行try / catch时,大多数IDE都会因分析代码流而感到沮丧。这就是为什么我需要没有try / catch的解决方案的原因。
胜利者。

4
小心。与匹配的正则表达式匹配以0开头的整数,然后将引发NumberFormatException。试试这个^:| $从([1-9] \ d * 0?)stackoverflow.com/questions/12018479/...

4
这个特殊的正则表达式不会处理负数。
布拉德·库皮

6
这也不包括超出整数范围的数字范围
Mohammad Yahia

10

Ints.tryParse()番石榴。它不会在非数字字符串上引发异常,但是会在空字符串上引发异常。


4

阅读问题的答案后,我认为封装或包装parseInt方法不是必需的,甚至可能不是一个好主意。

您可以按照乔恩(Jon)的建议返回“ null”,但这或多或少地用空检查代替了try / catch构造。如果您“忘记”错误处理,则行为上会有细微的差别:如果您没有捕获到异常,则没有赋值,并且左侧变量将其保留为旧值。如果不测试null,则可能会受到JVM(NPE)的攻击。

yawn的建议对我来说看起来更优雅,因为我不喜欢返回null来表示某些错误或异常状态。现在,您必须使用预定义的对象检查引用相等性,这表明存在问题。但是,正如其他人争辩的那样,如果再次“忘记”检查并且String无法解析,则程序将以“ ERROR”或“ NULL”对象内的包装int继续进行。

Nikolay的解决方案甚至更面向对象,并且也可以与其他包装类中的parseXXX方法一起使用。但最后,他只是用OperationNotSupported异常替换了NumberFormatException-再次需要尝试/捕获才能处理无法解析的输入。

因此,我的结论是不封装纯parseInt方法。我只封装我是否可以添加一些(取决于应用程序)错误处理。


4

可能您可以使用类似以下的内容:

public class Test {
public interface Option<T> {
    T get();

    T getOrElse(T def);

    boolean hasValue();
}

final static class Some<T> implements Option<T> {

    private final T value;

    public Some(T value) {
        this.value = value;
    }

    @Override
    public T get() {
        return value;
    }

    @Override
    public T getOrElse(T def) {
        return value;
    }

    @Override
    public boolean hasValue() {
        return true;
    }
}

final static class None<T> implements Option<T> {

    @Override
    public T get() {
        throw new UnsupportedOperationException();
    }

    @Override
    public T getOrElse(T def) {
        return def;
    }

    @Override
    public boolean hasValue() {
        return false;
    }

}

public static Option<Integer> parseInt(String s) {
    Option<Integer> result = new None<Integer>();
    try {
        Integer value = Integer.parseInt(s);
        result = new Some<Integer>(value);
    } catch (NumberFormatException e) {
    }
    return result;
}

}

我喜欢使用may模式的解决方案。非常客气;)
rodrigoelp

1
由于存在
Java.util.Optional

2

您还可以非常简单地复制所需的C ++行为

public static boolean parseInt(String str, int[] byRef) {
    if(byRef==null) return false;
    try {
       byRef[0] = Integer.parseInt(prop);
       return true;
    } catch (NumberFormatException ex) {
       return false;
    }
}

您将使用如下方法:

int[] byRef = new int[1];
boolean result = parseInt("123",byRef);

在该变量之后,result如果一切正常并byRef[0]包含已解析的值,则为true 。

就个人而言,我会坚持抓住例外。


2

乔恩·斯凯特(Jon Skeet)给出的答案很好,但是我不喜欢还给一个null整数对象。我觉得这令人困惑。由于Java 8有更好的选择(我认为),请使用OptionalInt

public static OptionalInt tryParse(String value) {
 try {
     return OptionalInt.of(Integer.parseInt(value));
  } catch (NumberFormatException e) {
     return OptionalInt.empty();
  }
}

这明确表明您必须处理没有可用值的情况。我希望将来将这种功能添加到java库中,但是我不知道这种情况是否会发生。



1

我的Java有点生锈,但是让我看看是否能为您指明正确的方向:

public class Converter {

    public static Integer parseInt(String str) {
        Integer n = null;

        try {
            n = new Integer(Integer.tryParse(str));
        } catch (NumberFormatException ex) {
            // leave n null, the string is invalid
        }

        return n;
    }

}

如果返回值为null,则您的价值不正确。否则,您有一个有效的Integer


OP希望转换结果(作为参考)以及转换成功(或不成功)的指示。
打呵欠

1
@yawn:空引用正好表示该指示。
乔恩·斯基特

@约翰·斯基特(John Skeet):正确,但我对他的意图有所不同。他写过类似使用中间对象来区分成功/失败+价值的东西。来自C ++背景,我认为如果他想使用null(而不是对象),他一开始就不会问这个问题。
打呵欠

“值”和“对象”之间有一个主要区别。空引用是一个纯净值,但不是对象。
乔恩·斯基特

1. Integer.tryParse标准Java Integer类中没有。2.这样做new Integer是不必要的(并且建议不要这样做),因为Java会自动进行装箱和拆箱。您的Java不仅有点生锈,而且非常生锈。
ADTC '17

1

怎么样建立该parseInt函数的方法?

这很简单,只需将内容复制粘贴到一个新的实用程序中,该实用程序将返回IntegerOptional<Integer>将引发替换为返回。底层代码中似乎没有例外,但最好检查一下

通过跳过整个异常处理内容,可以节省无效输入的时间。而且该方法自JDK 1.0起就存在,因此您不必为了使其保持最新状态而必须做很多事情。


0

我建议您考虑一种类似

 IntegerUtilities.isValidInteger(String s)

然后您可以根据自己的意愿实施。如果您希望将结果带回-也许是因为无论如何都使用Integer.parseInt()-您可以使用数组技巧。

 IntegerUtilities.isValidInteger(String s, int[] result)

将result [0]设置为在过程中找到的整数值。


0

这有点类似于尼古拉的解决方案:

 private static class Box<T> {
  T me;
  public Box() {}
  public T get() { return me; }
  public void set(T fromParse) { me = fromParse; }
 }

 private interface Parser<T> {
  public void setExclusion(String regex);
  public boolean isExcluded(String s);
  public T parse(String s);
 }

 public static <T> boolean parser(Box<T> ref, Parser<T> p, String toParse) {
  if (!p.isExcluded(toParse)) {
   ref.set(p.parse(toParse));
   return true;
  } else return false;
 }

 public static void main(String args[]) {
  Box<Integer> a = new Box<Integer>();
  Parser<Integer> intParser = new Parser<Integer>() {
   String myExclusion;
   public void setExclusion(String regex) {
    myExclusion = regex;
   }
   public boolean isExcluded(String s) {
    return s.matches(myExclusion);
   }
   public Integer parse(String s) {
    return new Integer(s);
   }
  };
  intParser.setExclusion("\\D+");
  if (parser(a,intParser,"123")) System.out.println(a.get());
  if (!parser(a,intParser,"abc")) System.out.println("didn't parse "+a.get());
 }

main方法演示代码。实现Parser接口的另一种方法显然是从构造中设置“ \ D +”,并使方法不执行任何操作。


0

可以自己动手,但使用commons lang的StringUtils.isNumeric() 方法一样容易。它使用Character.isDigit()遍历String中的每个字符。


然后,如果数字包含太大的数字将不起作用。对于大于Integer.MAX_VALUE的数字,Integer.parseInt引发异常(对于负数当然也是如此)。
塞尔斯

0

他们以递归方式处理这个问题。例如,当从控制台读取数据时:

Java.util.Scanner keyboard = new Java.util.Scanner(System.in);

public int GetMyInt(){
    int ret;
    System.out.print("Give me an Int: ");
    try{
        ret = Integer.parseInt(keyboard.NextLine());

    }
    catch(Exception e){
        System.out.println("\nThere was an error try again.\n");
        ret = GetMyInt();
    }
    return ret;
}

0

为避免异常,可以使用Java的Format.parseObject方法。下面的代码基本上是Apache Common的IntegerValidator类的简化版本。

public static boolean tryParse(String s, int[] result)
{
    NumberFormat format = NumberFormat.getIntegerInstance();
    ParsePosition position = new ParsePosition(0);
    Object parsedValue = format.parseObject(s, position);

    if (position.getErrorIndex() > -1)
    {
        return false;
    }

    if (position.getIndex() < s.length())
    {
        return false;
    }

    result[0] = ((Long) parsedValue).intValue();
    return true;
}

您可以根据自己的喜好使用AtomicInteger或使用int[]数组技巧。

这是我使用它的测试-

int[] i = new int[1];
Assert.assertTrue(IntUtils.tryParse("123", i));
Assert.assertEquals(123, i[0]);

0

我也有同样的问题。这是我写的一种方法,要求用户提供输入,除非输入为整数,否则不接受输入。请注意,我是一个初学者,所以如果代码无法正常工作,请怪我没有经验!

private int numberValue(String value, boolean val) throws IOException {
    //prints the value passed by the code implementer
    System.out.println(value);
    //returns 0 is val is passed as false
    Object num = 0;
    while (val) {
        num = br.readLine();
        try {
            Integer numVal = Integer.parseInt((String) num);
            if (numVal instanceof Integer) {
                val = false;
                num = numVal;
            }
        } catch (Exception e) {
            System.out.println("Error. Please input a valid number :-");
        }
    }
    return ((Integer) num).intValue();
}

1
不要使用System.out.println(这是一种不好的做法)。使用它的问题是您的程序将等到println完成。更好的方法是使用日志记录框架。
Omar Hrynkiewicz

0

这是对问题8391979的回答,该问题已关闭并链接到该问题:“ java是否有一个int.tryparse不会为不良数据引发异常?[重复]”。

编辑2016年8月17日:添加了ltrimZeroes方法,并在tryParse()中对其进行了调用。在numberString中不带前导零的情况下,可能给出错误的结果(请参阅代码中的注释)。现在还存在公共静态String ltrimZeroes(String numberString)方法,该方法适用于正数和负数“数字”(END Edit)

在下面,您可以找到一个用于int的基本Wrapper(拳击)类,该类具有高速优化的tryParse()方法(类似于C#),该方法可以解析字符串本身,并且比Java中的Integer.parseInt(String s)快一点:

public class IntBoxSimple {
    // IntBoxSimple - Rudimentary class to implement a C#-like tryParse() method for int
    // A full blown IntBox class implementation can be found in my Github project
    // Copyright (c) 2016, Peter Sulzer, Fürth
    // Program is published under the GNU General Public License (GPL) Version 1 or newer

    protected int _n; // this "boxes" the int value

    // BEGIN The following statements are only executed at the
    // first instantiation of an IntBox (i. e. only once) or
    // already compiled into the code at compile time:
    public static final int MAX_INT_LEN =
            String.valueOf(Integer.MAX_VALUE).length();
    public static final int MIN_INT_LEN =
            String.valueOf(Integer.MIN_VALUE).length();
    public static final int MAX_INT_LASTDEC =
            Integer.parseInt(String.valueOf(Integer.MAX_VALUE).substring(1));
    public static final int MAX_INT_FIRSTDIGIT =
            Integer.parseInt(String.valueOf(Integer.MAX_VALUE).substring(0, 1));
    public static final int MIN_INT_LASTDEC =
            -Integer.parseInt(String.valueOf(Integer.MIN_VALUE).substring(2));
    public static final int MIN_INT_FIRSTDIGIT =
            Integer.parseInt(String.valueOf(Integer.MIN_VALUE).substring(1,2));
    // END The following statements...

    // ltrimZeroes() methods added 2016 08 16 (are required by tryParse() methods)
    public static String ltrimZeroes(String s) {
        if (s.charAt(0) == '-')
            return ltrimZeroesNegative(s);
        else
            return ltrimZeroesPositive(s);
    }
    protected static String ltrimZeroesNegative(String s) {
        int i=1;
        for ( ; s.charAt(i) == '0'; i++);
        return ("-"+s.substring(i));
    }
    protected static String ltrimZeroesPositive(String s) {
        int i=0;
        for ( ; s.charAt(i) == '0'; i++);
        return (s.substring(i));
    }

    public static boolean tryParse(String s,IntBoxSimple intBox) {
        if (intBox == null)
            // intBoxSimple=new IntBoxSimple(); // This doesn't work, as
            // intBoxSimple itself is passed by value and cannot changed
            // for the caller. I. e. "out"-arguments of C# cannot be simulated in Java.
            return false; // so we simply return false
        s=s.trim(); // leading and trailing whitespace is allowed for String s
        int len=s.length();
        int rslt=0, d, dfirst=0, i, j;
        char c=s.charAt(0);
        if (c == '-') {
            if (len > MIN_INT_LEN) { // corrected (added) 2016 08 17
                s = ltrimZeroesNegative(s);
                len = s.length();
            }
            if (len >= MIN_INT_LEN) {
                c = s.charAt(1);
                if (!Character.isDigit(c))
                    return false;
                dfirst = c-'0';
                if (len > MIN_INT_LEN || dfirst > MIN_INT_FIRSTDIGIT)
                    return false;
            }
            for (i = len - 1, j = 1; i >= 2; --i, j *= 10) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt -= (c-'0')*j;
            }
            if (len < MIN_INT_LEN) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt -= (c-'0')*j;
            } else {
                if (dfirst >= MIN_INT_FIRSTDIGIT && rslt < MIN_INT_LASTDEC)
                    return false;
                rslt -= dfirst * j;
            }
        } else {
            if (len > MAX_INT_LEN) { // corrected (added) 2016 08 16
                s = ltrimZeroesPositive(s);
                len=s.length();
            }
            if (len >= MAX_INT_LEN) {
                c = s.charAt(0);
                if (!Character.isDigit(c))
                    return false;
                dfirst = c-'0';
                if (len > MAX_INT_LEN || dfirst > MAX_INT_FIRSTDIGIT)
                    return false;
            }
            for (i = len - 1, j = 1; i >= 1; --i, j *= 10) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt += (c-'0')*j;
            }
            if (len < MAX_INT_LEN) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt += (c-'0')*j;
            }
            if (dfirst >= MAX_INT_FIRSTDIGIT && rslt > MAX_INT_LASTDEC)
                return false;
            rslt += dfirst*j;
        }
        intBox._n=rslt;
        return true;
    }

    // Get the value stored in an IntBoxSimple:
    public int get_n() {
        return _n;
    }
    public int v() { // alternative shorter version, v for "value"
        return _n;
    }
    // Make objects of IntBoxSimple (needed as constructors are not public):
    public static IntBoxSimple makeIntBoxSimple() {
        return new IntBoxSimple();
    }
    public static IntBoxSimple makeIntBoxSimple(int integerNumber) {
        return new IntBoxSimple(integerNumber);
    }

    // constructors are not public(!=:
    protected IntBoxSimple() {} {
        _n=0; // default value an IntBoxSimple holds
    }
    protected IntBoxSimple(int integerNumber) {
        _n=integerNumber;
    }
}

类IntBoxSimple的测试/示例程序:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class IntBoxSimpleTest {
    public static void main (String args[]) {
        IntBoxSimple ibs = IntBoxSimple.makeIntBoxSimple();
        String in = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        do {
            System.out.printf(
                    "Enter an integer number in the range %d to %d:%n",
                        Integer.MIN_VALUE, Integer.MAX_VALUE);
            try { in = br.readLine(); } catch (IOException ex) {}
        } while(! IntBoxSimple.tryParse(in, ibs));
        System.out.printf("The number you have entered was: %d%n", ibs.v());
    }
}

0

尝试使用正则表达式和默认参数参数

public static int parseIntWithDefault(String str, int defaultInt) {
    return str.matches("-?\\d+") ? Integer.parseInt(str) : defaultInt;
}


int testId = parseIntWithDefault("1001", 0);
System.out.print(testId); // 1001

int testId = parseIntWithDefault("test1001", 0);
System.out.print(testId); // 1001

int testId = parseIntWithDefault("-1001", 0);
System.out.print(testId); // -1001

int testId = parseIntWithDefault("test", 0);
System.out.print(testId); // 0

如果您使用的是apache.commons.lang3,则使用NumberUtils

int testId = NumberUtils.toInt("test", 0);
System.out.print(testId); // 0

0

如果一个人特别要求整数,我想提出另一个可行的建议:只需使用long并在错误情况下使用Long.MIN_VALUE。这类似于在Reader中用于char的方法,其中Reader.read()返回char范围内的整数;如果reader为空,则返回-1。

对于Float和Double,可以类似的方式使用NaN。

public static long parseInteger(String s) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return Long.MIN_VALUE;
    }
}


// ...
long l = parseInteger("ABC");
if (l == Long.MIN_VALUE) {
    // ... error
} else {
    int i = (int) l;
}

0

考虑到现有的答案,我已经复制粘贴并增强了源代码Integer.parseInt来完成这项工作,而我的解决方案

  • 不使用可能会很慢的try-catch(与Lang 3 NumberUtils不同),
  • 不使用不能捕获太大数字的正则表达式,
  • 避免拳击(与番石榴不同Ints.tryParse()),
  • 不需要任何的分配(不像int[]BoxOptionalInt),
  • 接受其中的任何CharSequence或一部分,而不是整个String
  • 可以使用Integer.parseInt可以[2,36]的任何基数
  • 不依赖于任何库。

唯一的缺点是toIntOfDefault("-1", -1)和之间没有区别toIntOrDefault("oops", -1)

public static int toIntOrDefault(CharSequence s, int def) {
    return toIntOrDefault0(s, 0, s.length(), 10, def);
}
public static int toIntOrDefault(CharSequence s, int def, int radix) {
    radixCheck(radix);
    return toIntOrDefault0(s, 0, s.length(), radix, def);
}
public static int toIntOrDefault(CharSequence s, int start, int endExclusive, int def) {
    boundsCheck(start, endExclusive, s.length());
    return toIntOrDefault0(s, start, endExclusive, 10, def);
}
public static int toIntOrDefault(CharSequence s, int start, int endExclusive, int radix, int def) {
    radixCheck(radix);
    boundsCheck(start, endExclusive, s.length());
    return toIntOrDefault0(s, start, endExclusive, radix, def);
}
private static int toIntOrDefault0(CharSequence s, int start, int endExclusive, int radix, int def) {
    if (start == endExclusive) return def; // empty

    boolean negative = false;
    int limit = -Integer.MAX_VALUE;

    char firstChar = s.charAt(start);
    if (firstChar < '0') { // Possible leading "+" or "-"
        if (firstChar == '-') {
            negative = true;
            limit = Integer.MIN_VALUE;
        } else if (firstChar != '+') {
            return def;
        }

        start++;
        // Cannot have lone "+" or "-"
        if (start == endExclusive) return def;
    }
    int multmin = limit / radix;
    int result = 0;
    while (start < endExclusive) {
        // Accumulating negatively avoids surprises near MAX_VALUE
        int digit = Character.digit(s.charAt(start++), radix);
        if (digit < 0 || result < multmin) return def;
        result *= radix;
        if (result < limit + digit) return def;
        result -= digit;
    }
    return negative ? result : -result;
}
private static void radixCheck(int radix) {
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        throw new NumberFormatException(
                "radix=" + radix + " ∉ [" +  Character.MIN_RADIX + "," + Character.MAX_RADIX + "]");
}
private static void boundsCheck(int start, int endExclusive, int len) {
    if (start < 0 || start > len || start > endExclusive)
        throw new IndexOutOfBoundsException("start=" + start + " ∉ [0, min(" + len + ", " + endExclusive + ")]");
    if (endExclusive > len)
        throw new IndexOutOfBoundsException("endExclusive=" + endExclusive + " > s.length=" + len);
}

-1

您可以像这样使用Null-Object:

public class Convert {

    @SuppressWarnings({"UnnecessaryBoxing"})
    public static final Integer NULL = new Integer(0);

    public static Integer convert(String integer) {

        try {
            return Integer.valueOf(integer);
        } catch (NumberFormatException e) {
            return NULL;
        }

    }

    public static void main(String[] args) {

        Integer a = convert("123");
        System.out.println("a.equals(123) = " + a.equals(123));
        System.out.println("a == NULL " + (a == NULL));

        Integer b = convert("onetwothree");
        System.out.println("b.equals(123) = " + b.equals(123));
        System.out.println("b == NULL " + (b == NULL));

        Integer c = convert("0");
        System.out.println("equals(0) = " + c.equals(0));
        System.out.println("c == NULL " + (c == NULL));

    }

}

此示例中main的结果是:

a.equals(123) = true
a == NULL false
b.equals(123) = false
b == NULL true
c.equals(0) = true
c == NULL false

这样,您始终可以测试转换失败,但仍可以将结果作为Integer实例使用。您可能还需要调整NULL表示的数字(≠0)。


如果“字符串整数”是字符串文字“ 0”怎么办?您永远不会知道输入是否无效。
巴特·基尔斯

我猜这取决于两个整数的==运算符是比较值还是引用。如果比较值,则存在问题。如果它比较引用,它将以与我的答案等效的方式工作。
亚当·马拉斯

为什么要下票?我的回答是正确的,并且提供了一个优势(超过null),您始终可以处理有效的Integer实例(而不是null),从而使您不必处理NPE。
打呵欠

不过,将实数与实数区分开是很有用的。您应该测试结果是否为空,以了解解析是否成功。IMO将隐藏在后面以及其他可以使用的对象隐藏起来的问题的根源。
乔恩·斯基特

更多下注-有趣!既然/ me是SO的新手,那么一位选民可以向我解释为什么?
打呵欠

-1

您不应该使用Exceptions来验证您的值

对于单个字符,有一个简单的解决方案:

Character.isDigit()

对于更长的值,最好使用一些工具。Apache提供的NumberUtils在这里可以完美地工作:

NumberUtils.isNumber()

请检查https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html


«检查字符串是否为有效的Java数字。有效数字包括标有0x限定符的十六进制,科学计数法和标有类型限定符的数字(例如123L)。» 这不是可以解析的Integer.parseInt
Miha_x64
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.