同一类型的扫描仪方法在一个地方工作,但在另一个地方不工作。。。如果这改变了任何答案,我将使用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)
投资调试NullPointerException(也称为NPE)。您可以查阅Progman评论的链接。
从上到下遵循例外情况(此处为NPE):
java.lang.空指针异常:无法调用java.util.Scanner.next线(),因为ls为空
在jeppJepQA. get答案(JepQA. java: 60)
在杰普。杰普吉。执行的操作(JepGui.java:268)
从堆栈跟踪中的前3行可以看到:
Scanner
变量ls
为空。这就是为什么对它的任何方法调用,如ls.nextLine()
都会在NPE中失败。JepQA
中,在文件第60行的getACK
方法中 在方法中,您将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
。
原因可能是:
String
传递给FileInputStream
构造函数的参数为null
。检查或调试打印“triviaA”文件选择.txt“
。还要确保fileChoose
本身不是null
,否则作为参数传递的整个串联表达式也将是null
FileNotFoundException
的异常。但是,为什么它没有被捕获并作为错误打印出来呢
fileChoose
为null
,结果是连接的路径名(文件名)。然后从构造器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()
可能会抛出什么
仅仅捕获异常是不够的;您还必须相应地更改代码路径。
您的代码具有以下格式:
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设计为介于基本体和类之间。 例如 注意: