
本文详解如何修正泛型UserInput类中因Scanner.next()返回字符串导致的ClassCastException,通过函数式接口动态解析输入类型,实现对Integer、Double等数值类型的正确读取与数学运算。
本文详解如何修正泛型userinput
问题根源在于:Scanner.next() 始终返回String类型,而代码中直接强制转换为泛型T(如Integer)——这种未经解析的强制转型在运行时必然失败,因为"123"字符串对象无法被直接转为Integer实例。
正确的解决方案是将类型解析逻辑外移,由调用方明确指定如何将输入流转化为目标类型。为此,我们重构UserInput类,使用java.util.function.Function
以下是重构后的完整实现:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
import java.util.*;
import java.util.function.Function;
import java.util.Scanner;
public class UserInput<t> {
private final Function<scanner t> reader;
public UserInput(Function<scanner t> reader) {
this.reader = reader;
}
public List<t> getUserInput(int number_inputs) {
List<t> inputs = new ArrayList();
Scanner input = new Scanner(System.in); // ✅ 单例Scanner,避免资源泄漏与重复初始化
for (int i = 1; i <p>在主程序中,按需传入对应的方法引用即可:</p>
<pre class="brush:php;toolbar:false;">public class CalculateValues {
public static void main(String[] args) {
// ✅ 读取Integer:自动调用 Scanner.nextInt()
UserInput<integer> intInput = new UserInput(Scanner::nextInt);
List<integer> intVals = intInput.getUserInput(2);
System.out.println("Sum of integers: " + (intVals.get(0) + intVals.get(1)));
// ✅ 读取Double:自动调用 Scanner.nextDouble()
UserInput<double> doubleInput = new UserInput(Scanner::nextDouble);
List<double> doubleVals = doubleInput.getUserInput(2);
System.out.println("Average: " + (doubleVals.get(0) + doubleVals.get(1)) / 2.0);
}
}</double></double></integer></integer>
⚠️ 关键注意事项:
- 绝不使用(T) input.next():这是类型不安全的源头,JVM无法在运行时凭空将String转为任意数值类型。
-
方法引用优先:Scanner::nextInt、Scanner::nextDouble等已内置方法简洁可靠;若需自定义类型(如BigDecimal),可用Lambda:
new UserInput(scanner -> new BigDecimal(scanner.next())) - Scanner生命周期管理:应在读取完成后显式调用close(),或改由外部传入已配置好的Scanner实例(更灵活、可测试)。
- 异常处理增强建议:实际项目中应在getUserInput()内包裹try-catch,捕获InputMismatchException等,提供友好的错误提示与重试机制。
该设计遵循“依赖倒置”原则——UserInput不再承担类型解析职责,而是专注流程控制;具体解析策略由调用方注入,既保证类型安全,又保持高度复用性与可扩展性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










