当前位置: 首页 > 知识库问答 >
问题:

Java扫描器未在一个字符串()中初始化,即使它在另一个字符串()中初始化

太叔京
2023-03-14

同一类型的扫描仪方法在一个地方工作,但在另一个地方不工作。。。如果这改变了任何答案,我将使用eclipse作为我的代码编辑器。如果不是在这里,所有变量都已在别处声明。

如果有人知道如何解决这个问题,我将永远感激你:)

这一个正在工作:

private String questionPicker(String str) 
{
    question = (int)(Math.random()*42);
    System.out.println(question);
    fileChoose = str.toUpperCase();
    String returnee;
    
    Scanner is = null;
    try 
    {
        is = new Scanner(new FileInputStream("triviaQ"+fileChoose+".txt"));
    }
    catch(FileNotFoundException z)
    {
        System.out.println("Error 004: File retrieve failed.");
    }
    skipLines(is, question);
    returnee = is.nextLine();
    is.close();
    return returnee;
}

这个不起作用:

public String getAnswer() 
{
    String returnee;
    
    Scanner ls = null;
    try 
    {
        ls = new Scanner(new FileInputStream("triviaA"+fileChoose+".txt"));
    }
    catch(FileNotFoundException z)
    {
        System.out.println("Error 004: File retrieve failed.");
    }
    skipLines(ls, question);
    returnee = ls.nextLine();
    ls.close();
    return returnee;
}

错误消息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "java.util.Scanner.nextLine()" because "ls" is null
at jepp.JepQA.getAnswer(JepQA.java:60)
at jepp.JepGui.actionPerformed(JepGui.java:268)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6617)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6382)
at java.desktop/java.awt.Container.processEvent(Container.java:2264)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4993)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2322)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4825)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4934)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4563)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4504)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2308)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2773)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4825)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

共有2个答案

柯天宇
2023-03-14

投资调试NullPointerException(也称为NPE)。您可以查阅Progman评论的链接。

从上到下遵循例外情况(此处为NPE):

java.lang.空指针异常:无法调用java.util.Scanner.next线(),因为ls为空

在jeppJepQA. get答案(JepQA. java: 60)

在杰普。杰普吉。执行的操作(JepGui.java:268)

从堆栈跟踪中的前3行可以看到:

  1. 您的Scanner变量ls为空。这就是为什么对它的任何方法调用,如ls.nextLine()都会在NPE中失败。
  2. 失败的调用在类JepQA中,在文件第60行的getACK方法中
  3. 方法是由动作处理程序调用的,方法是在JepGui中执行的

在方法中,您将ls初始化为null,这是可以的。然后,在try块中,您打开连接到路径所给文件的FileInputStream上的扫描仪:

try {
    ls = new Scanner(new FileInputStream("triviaA"+fileChoose+".txt"));
} catch(FileNotFoundException z) {
    System.out.println("Error 004: File retrieve failed.");
}

这个扫描仪分配,正是InputStream的打开失败了,因此ls在这里又变成了null

原因可能是:

  1. String传递给FileInputStream构造函数的参数为null。检查或调试打印“triviaA”文件选择.txt“。还要确保fileChoose本身不是null,否则作为参数传递的整个串联表达式也将是null
  2. 打开流或Sanner时出现类似于FileNotFoundException的异常。但是,为什么它没有被捕获并作为错误打印出来呢
  3. 所以,一定还有另一个问题!回到(1):假设fileChoosenull,结果是连接的路径名(文件名)。然后从构造器FileInputStream(String)或FileInputStream(File)的文档中读取,它可能会从路径名String内部创建一个文件,并查看其中的说明:

抛出:NullPointerException-如果路径名参数为null

更新:感谢k314159对我的假设做出的伪造推理的评论:

  • 可能的根本原因(2):错误打印在标准输出(控制台)上,在使用GUI时可轻松监控

说明:

>

因此(2)必须是最可能的根本原因。但是,FileNotFoundException可能是由fileChoose=null或为构造Scanner实例而传递的任何其他无效路径引起的。

您的文件名作为参数路径名传递到FileInputStream构造函数 为null 可能是无效的,因为fileSelect变量为null或其他。

比较另一种工作方法问题选择器(String str),在那里您将其分配为fileSelect=str.toUpperCase();。如果您将一个str作为null传递到这里,那么它也可能会抛出一个NPE。

添加一条保护语句(请参阅Fail fast principle)。例如,使用对象。requirennull(fileChoose,“答案/问题文件不能为空”) 其中第二条是当fileChoose为空时打印的错误消息

另请参见:为什么要使用对象。requireNonNull()?

波希米亚人的回答正确地指出了设计问题:

  • 语句的顺序和依赖关系(ls相关)
  • 在I/O-Stream事务中不寻常地应用try/catch/fint模式

如果这些是粗略概述的,这里有一个完整的前/后示例,并解释注释。

之前:

String returnee; // consider a default return value to avoid any null at the end

Scanner ls = null; // a null Scanner is useless, consider initializing inside try (local scope is safer)!
try { // try block can encompass the whole attempt with every dependent statement
    ls = new Scanner(new FileInputStream("triviaA"+fileChoose+".txt")); // test filename at least for non-null, before try block!
} catch(FileNotFoundException z) { //
    System.out.println("Error 004: File retrieve failed."); // perfect to log
    // but how to handle: return or assign returnee with a default 
}

skipLines(ls, question); // depends on ls, so put inside try-block
returnee = ls.nextLine(); // depends on ls, so put inside try-block

ls.close(); // safe resources: close inside finally-block!

return returnee; // what if this is (still) null

结合波希米亚的第二个轮廓图案:

  • 里面的所有东西都试着抓住最后一块

之后:

// default return
String returnee = ""; // default return value

// guard-statement with fail-fast
if (fileChoose == null) {
   return returnee; // returns the default or throw
}

String filename = "triviaA"+fileChoose+".txt"; // can not fail, because validated before. Worst case, e.g. least "triviaA.txt"

try { // block of ls dependent statements

   Scanner ls = new Scanner(new FileInputStream(filename)); // filename not-null
   skipLines(ls, question); // safer, because in local/try scope
   returnee = ls.nextLine(); // safer, but may throw NoSuchElementException

} catch(FileNotFoundException notFound) { //
    System.out.println("Error 004: File retrieve failed: " + notFound.getMessage()); // perfect to log
    // but how to handle: return or assign returnee with a default 
} catch(NoSuchElementException noElement)
    // log
    // and handle!
} finally {
    if (ls != null) ls.close(); // always close (if not null)
}

return returnee; // Avoid null, at least a default. Benefit: no NPE-risk for the caller.

另请参阅:Sanner.nextLine()可能会抛出什么

薛烈
2023-03-14

仅仅捕获异常是不够的;您还必须相应地更改代码路径。

您的代码具有以下格式

Scanner ls = null;
try {
    ls = new Scanner(...);
} catch(FileNotFoundException z) {
    // print error message
}
// do something with ls

如果发生异常,则在打印错误消息后继续执行,ls在执行“用ls做点什么”代码时仍将为null,这就是为什么会出现NullPointerException

要修复此问题,请在异常情况下退出该方法:

Scanner ls = null;
try {
    ls = new Scanner(...);
} catch(FileNotFoundException z) {
    // print error message
    return;
}
// do something with ls

或者将使用ls的代码移动到try中:

try {
    Scanner ls = new Scanner(...);
    // do something with ls
} catch(FileNotFoundException z) {
    // print error message
}

注意,对于上一个版本,我们不仅保存了一行代码(赋值和声明为一行),而且ls的范围仅限于try块;限制范围是良好的编码实践。

 类似资料:
  • 问题内容: 我知道对于上面的第3个初始化,字符串对象在字符串池中初始化,而第4个与字符串池无关。 1.和2有 什么区别?如果我将其视为指针变量,它存储的是特定内存地址,而该内存地址从未被JVM或OS使用? 4.和5 之间有区别吗? 当我打印和通过直接和,对,我甚至无法通过compilation.For ,编译OK,我得到“空”,并在控制台窗口中的输出。为什么? @aioobe的答案后编辑:更多问题

  • 在我的应用程序中,一切正常,但我想提高性能并优化我的代码。 这两个哪个更适合 1.initialisation 2.连接

  • 据我所知,在Java11中,这两个操作可以在一行中完成,不是吗?

  • 问题内容: 显然,javac中初始化字符串的大小受到限制。谁能帮助我确定最大限额? 谢谢 编辑: 我们正在构建一个初始化字符串,看起来像这样的“ {1,2,3,4,5,6,7,8 ......}”,但理想情况下应包含10,000个数字。当我们为1000执行此操作时,10,000会引发错误,提示代码对于try语句而言太大。 为了产生这种效果,我们使用了一个stringbuilder并在附加值的数组上

  • 问题内容: Go Newbie问题:我正在尝试使用默认值初始化以下结构。我知道,如果“ Uri”是字符串而不是指向字符串(* string)的指针,则可以使用。但是我需要这个指针来比较结构的两个实例,如果未设置Uri,则Uri将为nil,例如,当我从json文件解组内容时。但是,如何正确地将这样的结构初始化为“静态默认值”呢? 上面的代码因 问题答案: 无法获得(指向)常数值的地址,这就是初始化失

  • 问题内容: 如果String和其他字符串一样是一个类,如何使用双引号将其初始化? 问题答案: Java的设计者决定保留面向对象语言中的原始类型,而不是将所有内容都变成对象,以提高语言的性能。原语存储在调用堆栈中,这需要较少的存储空间,并且操作成本较低。另一方面,对象存储在程序堆中,这需要复杂的内存管理和更多的存储空间。 出于性能原因,Java的String设计为介于基本体和类之间。 例如 注意: