为了省6个单词,找了半个多小时的错误

本文探讨了在Java中将Scanner置于try-resource-catch块内导致的问题,详细解析了System.in流被提前关闭的原因及解决方案。

今天在写一个小demo的时候,用到了Scanner,然后我灵机一动。。想着把它放在try-resource-catch里面,因为正好是要用jdbc,所以想利用一下这个resource,于是我就把它放进去了,结果,发生了接下来的一幕。。。

我们来看一下代码

这里就是问题的根源

package jdbc_day1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class TestLogin {
	static {
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public static String login() {
		try (Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
				PreparedStatement ps = conn.prepareStatement("select * from tbl_user where name = ? and pwd = ?");
				Scanner s = new Scanner(System.in);
				) {
			boolean bn;
			//Scanner s = new Scanner(System.in);
			do {
				bn = false;
				System.out.print("请输入帐号");
				String name = s.next();
				System.out.print("请输入密码");
				String pwd = s.next();
				ps.setString(1, name);
				ps.setString(2, pwd);
				ResultSet rs = ps.executeQuery();
				if (rs.next()) {
					System.out.println("登录成功!");
					return name;
				} else {
					System.out.println("登录失败!");
					System.out.println("重新输入-y  退出-n");
					char c = s.next().charAt(0);
					bn = (c == 'y' || c == 'Y') ? true : false;
				}
				rs.close();
			} while (bn);
			//s.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
}

测试类

package jdbc_day1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class TestUpdate {
	static {
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		try (Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
				PreparedStatement ps = conn.prepareStatement("update tbl_user set pwd = ? where name = ?");) {
			String name = TestLogin.login();
			Scanner s = new Scanner(System.in);
			if (name != null) {
				System.out.print("请输入新密码:");
				String newPwd = s.next();
				ps.setString(1, newPwd);
				ps.setString(2, name);
				ps.executeUpdate();
				System.out.println("修改成功!");
			}
			s.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

美滋滋的写完了,想着,我真是太机智了,又省了六行代码~~ 舒服

当我运行的时候
在这里插入图片描述
报错了。。。 我找一下错误, 在25行,也就是下面这里
在这里插入图片描述

然后我就懵了,开始怀疑,难道是我昨晚喝多了? s.next()不是这么写的吗。。。然后我换成了s.nextLine();
结果还是如此. 此处省略很多问号。。。 接着,我打开了源码,也就是报错的位置,看下图
在这里插入图片描述

作为三级一遍过的男人,这点英文太简单了
(如果我们在输入的最后,那么NoSuchElement; 如果仍然有输入,那么input失配)
假装我没有用有道词典。但是,这翻译过来也看不懂啥玩意啊…

接着,费劲周折,我把Scanner放到外面,自己手动关闭,结果成功了

public static String login() {
		try (Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
				PreparedStatement ps = conn.prepareStatement("select * from tbl_user where name = ? and pwd = ?");) {
			boolean bn;
			Scanner s = new Scanner(System.in);
			do {
				bn = false;
				System.out.print("请输入帐号");
				String name = s.next();
				System.out.print("请输入密码");
				String pwd = s.next();
				ps.setString(1, name);
				ps.setString(2, pwd);
				ResultSet rs = ps.executeQuery();
				if (rs.next()) {
					System.out.println("登录成功!");
					return name;
				} else {
					System.out.println("登录失败!");
					System.out.println("重新输入-y  退出-n");
					char c = s.next().charAt(0);
					bn = (c == 'y' || c == 'Y') ? true : false;
				}
				rs.close();
			} while (bn);
			s.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

在这里插入图片描述
然后咱们来分析一下原因,这到底是为什么呢?
首先,咱们看一下System.in底层是什么样的
在这里插入图片描述

从这里可以看出System.in底层是封装的一个静态输入流
如果我们将Scanner放入try-resource-catch里面的话,会自动将所有资源关闭,当然包括这个输入流
所有当我们在测试类中调用完login方法之后,这个输入流in已经在login中关闭了,由于是静态的,所以我们在测试类中的in也是关闭的,这个时候,我们用一个关闭的流去接收键盘输入的值,就会报java.util.NoSuchElementException这个错误,但是如果我们手动关闭的话,当登陆成功后,就直接带着返回值返回到调用处了,而s.close();这个语句并没有执行,所以这个流还是开启的.因此就可以正常使用咯~~

从这里可以得到一个小小的经验:在我们使用键盘输入的时候,尽量手动关闭资源,不然稍不注意,可能就会犯我这个错误咯~~

<think>好的,我现在需要帮用户制定一个六级考试的学习计划,结合他们的情况。用户是大二学生,已经过了四级,现在准备6月的六级考试。首先,我得考虑六级和四级的区别在哪里。六级在词汇量、听力速度和阅读理解难度上都比四级高,所以需要针对性加强。用户可能已经有一定的英语基础,但需要更系统的复习。 用户的时间安排是关键。现在到6月大约有三个月的时间,合理分配每个阶段的任务很重要。可能需要分阶段进行,比如基础巩固、专项强化和冲刺模拟。每个阶段的目标要明确,比如前一个月背单词和练习听力,中间一个月加强阅读和写作,最后一个月做真题和模拟考试。 然后要考虑用户的学习习惯和时间管理。用户可能每天有2-3小时的学习时间,需要高效利用。背单词可以用碎片时间,比如早晚各半小时。听力需要每天坚持,阅读和写作可以隔天交替进行。真题练习每周至少一次,模拟考试环境。 还要注意用户可能的薄弱环节。比如,如果听力是弱项,就需要听真题材料,练习精听和泛听。阅读方面,快速定位信息和理解复杂句子结构是关键。写作和翻译需要积累模板和常用表达,避免语法错误。 另外,推荐一些实用的学习资源,比如单词APP、真题集、在线课程等。同时,提醒用户注意复习方法,比如错题整理、定期复习单词、模拟考试的时间管理等。保持学习动力也很重要,可以设定小目标,每周检查进度,调整计划。 最后,整合这些点,形成一个详细但可行的计划,分阶段、分模块,帮助用户高效备考六级。要确保计划既有挑战性,又不至于压力过大,保持持续进步。</think>以下是为6月六级考试定制的3个月科学备考计划(含每日学习方案+重点突破策略): 一、阶段目标拆解(倒计时12周) $$ \text{基础重建期(W1-4)} \rightarrow \text{专项突破期(W5-8)} \rightarrow \text{全真模拟期(W9-12)} $$ 二、每日学习方案(建议每天2-3小时) 1. 晨间30分钟(7:30-8:00) - 高频词汇背诵:使用「不背单词」APP完成50词(重点:六级核心1300词) - 听力磨耳:循环播放前一天精听材料(1.2倍速) 2. 午间40分钟(12:30-13:10) - 阅读训练:精读1篇真题选词填空(标注长难句结构) - 翻译积累:整理5个中国特色词汇表达(如:一带一路 Belt and Road Initiative) 3. 晚间黄金90分钟(19:00-20:30) - 听力精练:完成1套真题听力(流程:做题→逐句听写→跟读) - 写作框架:学习1类作文模板(现象解释/观点对比/图表分析) - 错题复盘:建立Excel错题本(记录错误类型+解决策略) 三、重点突破策略(按题型分类) 1. 听力提分方案(占总分35%) - 关键技巧: $$ \text{预判考点} + \text{视听一致} + \text{同义替换} $$ - 训练步骤: ```text 基础版(W1-4):每日精听1篇讲座(Section C) 进阶版(W5-8):1.25倍速泛听+笔记速记 冲刺版(W9-12):全真模拟+选项关键词预判 ``` 2. 阅读提速方案(占总分35%) - 三大题型攻克顺序: $$ \text{仔细阅读} \rightarrow \text{长篇阅读} \rightarrow \text{选词填空} $$ - 时间分配公式: $$ \frac{40\分钟}{总时间} = \frac{18\分钟}{仔细阅读} + \frac{15\分钟}{长篇阅读} + \frac{7\分钟}{选词填空} $$ - 定位技巧: ```text 题干关键词 → 原文定位 → 同义替换确认 → 排除干扰项 ``` 3. 写作翻译保分方案(占总分30%) - 写作模板构建: $$ \text{三段式结构} = \text{引言(现象描述)} + \text{主体(论点+论据)} + \text{结论(建议/展望)} $$ 常用句型示例: ```text "The statistical data reveals that..., which has sparked widespread debate regarding..." ``` - 翻译提分要点: - 先拆分句子主干 - 处理文化负载词(例:四合院→quadrangle courtyard) - 检查时态/语态/单复数 四、必备资料清单 1. 纸质材料: - 《星火英语六级真题详解》(最新3年真题) - 《六级词汇周计划》(高频词分类记忆) 2. 数字工具: - 欧路词典(内置牛津/柯林斯词典) - 每日英语听力(精听六级真题) - Quizlet(自制单词卡) 五、关键时间节点 1. 每周六上午9:00-11:20:全真模拟考试(严格计时) 2. 每月末:专项能力测试(使用星火预测卷) 3. 考前7天:高频词快速过筛(重点复习易错词) 六、常见问题应对策略 1. 听力跟不上语速: - 解决方案:从1.0倍速开始逐句听写,每周增加0.1倍速 2. 阅读时间不足: - 专项训练:使用「5-3-2法则」限时训练(5分钟短篇/3分钟匹配/2分钟选词) 3. 写作词汇单一: - 建立替换词库(例:important→crucial/vital/paramount) 七、进度自查表(每周日晚核对) - [ ] 完成3套听力精练 - [ ] 记忆200个高频词 - [ ] 精析5篇仔细阅读 - [ ] 背诵2类作文模板 - [ ] 整理10句翻译表达 特别提示:考前30天启动「真题轰炸模式」,重点研究近5年真题(尤其是2021年改革后的新题型)。建议参加6月1日的四六级模考大赛(中国教育考试网主办),提前适应考试节奏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值