
本文详解如何修正泛型userinput<t>类中因scanner.next()返回字符串导致的classcastexception,通过函数式接口动态解析输入类型,实现对integer、double等数值类型的正确读取与数学运算。
本文详解如何修正泛型userinput<t>类中因scanner.next()返回字符串导致的classcastexception,通过函数式接口动态解析输入类型,实现对integer、double等数值类型的正确读取与数学运算。
问题根源在于:Scanner.next() 始终返回String类型,而代码中直接强制转换为泛型T(如Integer)——这种未经解析的强制转型在运行时必然失败,因为"123"字符串对象无法被直接转为Integer实例。
正确的解决方案是将类型解析逻辑外移,由调用方明确指定如何将输入流转化为目标类型。为此,我们重构UserInput类,使用java.util.function.Function<Scanner, T>作为构造参数,封装类型专属的读取行为(如Scanner::nextInt、Scanner::nextDouble),避免任何不安全的强制转换。
以下是重构后的完整实现:
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 <= number_inputs; i++) { // ✅ 修正循环边界:i <= number_inputs
System.out.print("Enter number " + i + ": ");
T value = reader.apply(input);
inputs.add(value);
}
input.close(); // ✅ 及时关闭Scanner(生产环境建议由调用方管理)
return inputs;
}
}在主程序中,按需传入对应的方法引用即可:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
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);
}
}⚠️ 关键注意事项:
- 绝不使用(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不再承担类型解析职责,而是专注流程控制;具体解析策略由调用方注入,既保证类型安全,又保持高度复用性与可扩展性。

















