泛型Integer类型ArrayList意外存储String?技术咨询
解决泛型类中String转T类型的类型不匹配问题
嘿,这个问题我太熟了——本质上是你把文件里读出来的原始字符串直接塞给了泛型ArrayList<T>,但泛型要求的是Integer这类实现了Comparable的具体类型,类型不匹配当然会抛出运行时异常。下面给你一套清晰的解决方案:
核心思路
因为文件读取的内容都是String类型,而你的泛型类需要支持任意Comparable<T>类型,所以必须让调用者提供一个字符串到T类型的转换逻辑,这样才能保证类型安全。我们可以用Java 8+的Function函数式接口来实现这个灵活性。
修改后的泛型类代码
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.function.Function; public class SortsTextFile<T extends Comparable<T>> { private ArrayList<T> listFromFile = null; // 用于将文件行拆分后的字符串数组转换为T类型的转换器 private final Function<String[], T> lineConverter; // 假设你的FIELD_SEP是类内常量 private static final String FIELD_SEP = ","; // 构造方法必须传入转换器,明确类型转换规则 public SortsTextFile(Function<String[], T> lineConverter) { this.lineConverter = lineConverter; } public void readFromFile(String listInfo) throws IOException { try (BufferedReader in = new BufferedReader(new FileReader(listInfo))) { listFromFile = new ArrayList<>(); String line = in.readLine(); while (line != null) { String[] columns = line.split(FIELD_SEP); // 用转换器把字符串数组转成目标T类型,再加入集合 T item = lineConverter.apply(columns); listFromFile.add(item); // 读取下一行 line = in.readLine(); } } } // 可以加一个获取集合的方法 public ArrayList<T> getListFromFile() { return listFromFile; } }
使用示例
针对Integer类型的文件读取
假设你的文件每行是一个整数(比如123、456),或者每行用分隔符分隔的第一个字段是整数:
public class Main { public static void main(String[] args) { try { // 创建Integer类型的实例,指定转换规则:取数组第一个元素转成Integer SortsTextFile<Integer> intSorter = new SortsTextFile<>(columns -> Integer.parseInt(columns[0])); intSorter.readFromFile("integers.txt"); // 现在listFromFile里就是合法的Integer类型元素了 System.out.println(intSorter.getListFromFile()); } catch (IOException e) { e.printStackTrace(); } } }
针对自定义Comparable类型的读取
如果你有一个自定义的Person类实现了Comparable:
class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Person o) { return Integer.compare(this.age, o.age); } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } }
使用时只需要传入对应的转换逻辑:
public class Main { public static void main(String[] args) { try { // 假设文件每行格式是"张三,25",拆分后转成Person对象 SortsTextFile<Person> personSorter = new SortsTextFile<>(columns -> new Person(columns[0], Integer.parseInt(columns[1])) ); personSorter.readFromFile("people.txt"); System.out.println(personSorter.getListFromFile()); } catch (IOException e) { e.printStackTrace(); } } }
为什么之前的代码会出错?
因为泛型在编译时会被擦除,编译器可能没法提前检测到你把String塞进了ArrayList<Integer>里,但运行时JVM会检查实际类型,发现类型不匹配就抛出ClassCastException。通过传入明确的转换器,我们在把元素加入集合前就完成了类型转换,从根源上避免了这个问题。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

