java.lang.NumberFormatException:对于输入字符串:“”

Posted

技术标签:

【中文标题】java.lang.NumberFormatException:对于输入字符串:“”【英文标题】:java.lang.NumberFormatException: For input string: "" 【发布时间】:2010-09-13 14:49:12 【问题描述】:

运行此代码时:

JTextField ansTxt;
...
ansTxt = new JTextField(5);
String aString = ansTxt.getText();
int aInt = Integer.parseInt(aString);

为什么会出现这个错误?

线程“AWT-EventQueue-0”中的异常

更新:

JTextField ansTxt;
ansTxt = new JTextField(5);

ansTxt.addKeyListener(new KeyAdapter() 
   public void keyReleased(KeyEvent e) 
    ansTxt = (JTextField) e.getSource();
    String aString = ansTxt.getText().trim();
    int aInt = Integer.parseInt(aString);
   

【问题讨论】:

问题是什么?您确定 TextField 中有一个可解析的字符串,但它没有被拾取吗?或者您想知道如何确保正确处理不可解析的字符串? 我只是不明白为什么会出现错误。 什么时候出现错误?你不是在输入“5”然后按退格键吗? 不,我只是输入了任何数字而没有按退格键。它会自动切换到其他屏幕。 @Jessy 你用调试器检查过你输入的字符串是什么吗? 【参考方案1】:

JTextField constructor 的整数参数实际上是列数的宽度。来自文档:

public JTextField(int columns)

用指定的列数构造一个新的空 TextField。创建默认模型并将初始字符串设置为空。

通过构造它

ansTxt = new JTextField(5);

您基本上会得到一个空的文本字段(比使用无参数构造函数构造它时略)。如果你希望它包含字符串“5”,你应该写

ansTxt = new JTextField("5");
更新: IIRC,您将获得一个 keyDown 事件、一个 keyTyped 事件和一个 keyUp 事件。大概文本字段尚未在 keyDown 事件上更新。 无论哪种方式,我建议您将 Integer.parseInt 封装在
try  ...  catch (NumberFormatException e)  ... 
块,因为用户很可能会写除整数以外的其他内容。 -->

【讨论】:

很抱歉给您带来了困惑..是的,我已将宽度设置为 5 ...我要求用户在 JTextField 上键入任何字符串,而不是特别是 5...我试过修剪() 但它不起作用。 @Jessy 在问题中的代码中,用户没有机会做任何事情,因为 JTextField 已创建并立即解析。这是上面代码中的错误还是您的应用程序中的错误? @Jessy 我不确定你的意思,但这不是你发布的代码的作用。它创建一个新的文本字段,检索它包含的文本(默认为空字符串),并尝试将其转换为整数。 getText 不会提示用户输入文本,它只是从文本字段中提取当前文本 ansTxt = (JTextField) e.getSource();字符串 aString = ansTxt.getText().trim(); int aInt = Integer.parseInt(aString); 您需要(更新问题或创建新问题)和(提供更多上下文)。 e 来自哪里?【参考方案2】:

您正在尝试将空字符串解析为 int,但这是行不通的。应该将“”解析为哪个int? JTextField 需要有一个可以解析的文本。

ansTxt.addKeyListener(new KeyAdapter() 
    public void keyReleased(KeyEvent e) 
        ansTxt = (JTextField) e.getSource();
        try 
            int aInt = Integer.parseInt(ansTxt.getText());
            //Do whatever you want with the int
         catch(NumberFormatException nfe) 
            /*
             * handle the case where the textfield 
             * does not contain a number, e.g. show
             * a warning or change the background or 
             * whatever you see fit.
             */
        
    

在 KeyAdapter 中设置 ansTxt 也可能不是一个好主意。我建议您为此使用局部变量。这也使得将适配器移动到“真实”类而不是匿名类更容易。

【讨论】:

【参考方案3】:

使用方法trim()

int m=Integer.parseInt(txtfield.getText().trim());  

trim() 方法将删除附加到数字的任何字符串。

【讨论】:

【参考方案4】:

您的 KeyAdapter 将在您的 ansText 处理 KeyEvent 之前运行。事实上,你可以e.consume() 来阻止ansText 处理它。所以第一次按下和释放一个键时,ansText.getText() 仍然是""。这就是你第一次得到异常的原因。按数字键两次,第二次应该可以工作。

【讨论】:

【参考方案5】:

尝试将 Apache 的“commons Lang”库引入您的项目,最后一行您可以这样做

int aInt = 0;
if(StringUtils.isNotBlank(aString) && StringUtils.isNumeric(aString) )
    aInt = Integer.parseInt(aString);

编辑:不知道为什么投反对票。 JtextField 将采用任何字符串。如果文本字段在每次按键时都在监听,则输入的每个非数字值(包括空白)都将生成 NumberFormatException。最好在对新值进行任何操作之前检查它是否为 Numeric。

edit2:根据下面的 Thomas 的 cmets。我运行了一个测试来比较 try/catch 与 StringUtils 解决此问题的方法。每个测试运行 500 万次。 try/catch 的平均时间为 21 秒。 StringUtils 的平均时间为 8 秒。因此,使用 StringUtils 处理重负载要快得多。如果代码上的负载很小,您会注意到几乎没有差异。测试运行是

try
   result = Integer.parseInt(num);
catch(NumberFormatException ex)
   result = -1;

if(StringUtils.isNotBlank(num) && StringUtils.isNumeric(num))
   result = Integer.parseInt(num);
else
   result = -1;

每个循环都会生成一个新的 10 位随机字符串,以避免对 if 语句的循环进行任何优化。这增加了 6-7 秒的开销。

【讨论】:

您提出了一个额外的库,但没有给出应该使用它的理由。为什么这比尝试解析它并处理异常更好? @Thomas 捕获异常需要开销。在 StringUtils 中执行 isNumeric() 检查也有开销。所以归结为可维护性。我不希望捕获所有可能抛出的异常并在解析之前检查我的类型以避免异常,其他人可能不会。这取决于偏好。 这是一个交互式 GUI,响应按键。在您的测试中捕获异常的开销是每按下一个键 0,0000026 秒。我认为用户不会注意到 0,0026 毫秒的响应时间差异 是的,对于小型应用程序,我们两种方法之间的差异非常小。我一直听说使用 catch 语句有开销,但不知道有多少。我用这个问题作为练习来自己找出答案。对于这个问题,差异将是非常微不足道的,但在更大更时间敏感的应用程序中,上述分析可能会有所帮助。

以上是关于java.lang.NumberFormatException:对于输入字符串:“”的主要内容,如果未能解决你的问题,请参考以下文章