绕过泛型,通过反射把 String 添加到 List<Integer> 中

本文介绍了一种利用Java反射机制绕过泛型限制的方法,演示了如何将String类型的值添加到List&lt;Integer&gt;中。通过获取List的Class对象及add方法,并传递Object类型参数,实现了类型安全的规避。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

绕过泛型,通过反射把 String 添加到 List<Integer> 中

public class ArrayListDemo {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<Integer> list = new ArrayList<>();

        // list.add(1);
        // list.add(2);
        // list.add("hello");

        Class c = list.getClass();
        Method method = c.getMethod("add",Object.class);
        method.invoke(list,"hello");
        method.invoke(list,"world");
        method.invoke(list,"liwei");

        System.out.println(list);
    }
}
<think>好的,我现在需要帮助用户基于他们提供的List<Integer>的TypeHandler代码,编写一个处理Set<Integer>的转换器。首先,我要理解用户提供的代码结构和功能。用户给出的JsonToIntegerListTypeHandler类使用了MyBatis的TypeHandler接口,将List<Integer>与数据库中的JSON字符串进行转换。他们现在想要类似的代码,但处理的是Set<Integer>类。我的任务是调整现有代码,使其适用于Set。 首先,我需要确认TypeHandler接口的实现方式。原代码中,TypeHandlerList<Integer>,而新的类需要改为Set<Integer>。因此,类名应该更改为类似JsonToIntegerSetTypeHandler,同时修改@MappedTypes注解中的类为Set.class,这样MyBatis就知道这个处理器处理的是Set类。接下来,检查各个方法中的参数类。原代码中的parameter参数是List<Integer>,现在需要改为Set<Integer>。例如,在setParameter方法中,需要将List<Integer> parameter改为Set<Integer>parameter。此外,JSON序列化和反序列化的部分也需要调整,确保ObjectMapper正确处理Set类。 然后,查看parseJson方法。原代码中使用TypeReference<List<Integer>>来反序列化,现在需要改为TypeReference<Set<Integer>>,这样ObjectMapper才能正确地将JSON数组转换为Set,自动去重并保持无序性。 另外,需要注意Set和List在序列化时的区别。虽然存储的JSON结构可能相同(都是数组),但反序列化时,Set会自动去除重复元素,而List不会。因此,在测试时应当验证这一点,确保转换后的Set确实没有重复项。 还需要检查所有的导入语句是否正确,例如确保java.util.Set和相关的MyBatis注解正确引入。在setParameter方法中,处理异常的部分也需要保持一致性,错误信息应适当修改为Set相关的描述。 最后,测试这个新的TypeHandler是否在MyBatis配置中正确注册,并且在映射文件中正确使用。例如,在MyBatis的配置文件中添加这个处理器,或者在对应的字段上使用@TypeHandler注解,确保MyBatis在读写数据库时能够调用这个处理器。 可能遇到的问题包括:未正确修改导致类不匹配,或者JSON反序列化时未能正确转换为Set。需要确保所有出现List<Integer>的地方都替换为Set<Integer>,并且TypeReference也相应调整。此外,数据库中的JSON字段应能存储Set序列化后的字符串,通常是一个没有重复元素的数组。总结步骤: 1. 创建新的类JsonToIntegerSetTypeHandler,实现TypeHandler<Set<Integer>>。2. 修改@MappedTypes注解为Set.class。 3.替换所有List<Integer>为Set<Integer>。 4.调整TypeReference为Set<Integer>。 5.测试确保去重功能有效。 这样用户就可以在需要处理Set<Integer>的地方使用这个新的TypeHandler,确保数据在Java对象和数据库之间的正确转换。</think>以下是基于`Set<Integer>`的格式转换实现的`TypeHandler`: ```java @MappedJdbcTypes(JdbcType.VARCHAR) @MappedTypes(Set.class) // 修改注解映射类为Set public class JsonToIntegerSetTypeHandler implements TypeHandler<Set<Integer>> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public void setParameter(PreparedStatement ps, int i, Set<Integer> parameter, JdbcType jdbcType) throws SQLException { try { String json = objectMapper.writeValueAsString(parameter); ps.setString(i, json); } catch (JsonProcessingException e) { throw new SQLException("Error converting Set<Integer> to JSON", e); } } @Override public Set<Integer> getResult(ResultSet rs, String columnName) throws SQLException { return parseJson(rs.getString(columnName)); } @Override public Set<Integer> getResult(ResultSet rs, int columnIndex) throws SQLException { return parseJson(rs.getString(columnIndex)); } @Override public Set<Integer> getResult(CallableStatement cs, int columnIndex) throws SQLException { return parseJson(cs.getString(columnIndex)); } private Set<Integer> parseJson(String json) throws SQLException { if (json == null || json.trim().isEmpty()) { return new HashSet<>(); } try { // 使用TypeReference指定反序列化为Set<Integer> return objectMapper.readValue(json, new TypeReference<Set<Integer>>() {}); } catch (JsonProcessingException e) { throw new SQLException("Error parsing JSON to Set<Integer>", e); } } } ``` **修改说明:** 1. 将`List<Integer>`改为`Set<Integer>` 2. 修改`@MappedTypes`注解为`Set.class` 3. 在`parseJson`方法中使用`TypeReference<Set<Integer>>`替代原List的引用 4. 默认返回`new HashSet<>()`替代原ArrayList 5. 所有异常描述中的"List"改为"Set" **特性说明:** - 自动处理JSON数组与Set<Integer>的转换 - 自动去除重复元素(Set特性) - 保持元素无序性(Set特性) - 默认使用HashSet实现 - 处理空值返回空集合
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值