java:利用fastjson判断一个类型(java.lang.reflect.Type)是否是一个javabean

本文介绍了一种利用FastJSON库高效判断Java类型是否符合JavaBean标准的方法。通过检查ParserConfig类的getDeserializer方法返回值类型来判断是否为JavaBean。此方法避免了繁琐的类型检查过程。

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

fastjson中JSON.toJSON(Object javaObject)方法将一个java对象被序列化成json对象时,返回的对象类型有三种可能:JSONObject,JSONArray,原始类型(简单类型)。
最近在使用fastjson进行对java对象序列化和反序列化时,遇到一个问题:
需要判断一个类型(java.lang.reflect.Type)是否为一个java bean(这里所说的java bean并非完全符合JavaBean规范的类型,只要不是简单类型、Map、Collection、Array,能被fastjson序列化为JSONObject对象而不是JSONArray或简单类型就算),如果要自己实现这个代码还是挺复杂的,需要一大堆的类型判断。
研究了fastjson的代码之后,发现它也有这个判断需求(实现代码近200行,好复杂)。在fastjson的基础上实现这个判断就很方便了。
原理很简单 ,com.alibaba.fastjson.parser.ParserConfig类中有一个getDeserializer(Type)方法用于根据Type返回相应的反序列化器(Deserializer),如果返回的对象类型是JavaBeanDeserializer,这个Type肯定是个java bean对象。
如下代码:

import java.lang.reflect.Type;

import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;

public class TypeUtils{

	public static final boolean isJavaBean(Type type){
		if(null == type )
			throw new NullPointerException();
		// 根据 getDeserializer 返回值类型判断是否为 java bean 类型
		return ParserConfig.global.getDeserializer(type) instanceof JavaBeanDeserializer;
	}
}

### Java中因FastJSON引发的`UnsupportedOperationException`解决方案 在Java开发过程中,当使用阿里云提供的FastJSON库时,可能会遇到`java.lang.UnsupportedOperationsException`异常。此异常通常发生在尝试修改不可变集合(Immutable Collection)或者调用了未被支持的操作时。 以下是针对该问题的具体分析与解决办法: #### 1. **原因分析** FastJSON在序列化和反序列化的过程中,默认会生成一些特殊的集合类实例,这些集合可能是只读或不可变的。如果程序试图对这些集合执行写操作,则会抛出`UnsupportedOperationException`异常[^1]。 例如,在某些情况下,FastJSON返回的是`Collections.unmodifiableList()`或其他类似的不可变集合形式。这种设计是为了提高性能并减少内存开销,但在实际应用中可能导致不兼容的情况。 #### 2. **解决方法** ##### 方法一:自定义解析器 可以通过配置FastJSON来改变其默认行为,使其生成可变集合而非不可变集合。具体做法是在初始化阶段设置相应的属性: ```java import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; public class FastJsonSolution { public static void main(String[] args) { ParserConfig.getGlobalInstance().setAsmEnable(false); String jsonString = "{\"name\":\"test\", \"contact\":[\"phone\",\"email\"]}"; Stu1 stu = JSON.parseObject(jsonString, Stu1.class); // 修改集合内容不会报错 stu.getContact().add("address"); System.out.println(JSON.toJSONString(stu)); } } ``` 这里禁用了ASM字节码增强功能 (`ParserConfig.setAsmEnable(false)`),可以有效避免部分复杂场景下的异常情况[^2]。 ##### 方法二:手动转换集合类型 另一种更通用的方式是对反序列化的结果进行二次封装,将不可变集合显式转为可变集合后再继续后续逻辑处理。 ```java import java.util.ArrayList; import java.util.List; public class ManualConversionExample { public static List<String> convertToMutable(List<?> list){ return new ArrayList<>(list); } public static void main(String[] args) { String jsonStr = "{\"contacts\": [\"value1\", \"value2\"]}"; Stu2 student = JSON.parseObject(jsonStr, Stu2.class); student.setId(convertToMutable(student.getId())); // 正常添加元素到列表中 student.getId().add("newId"); System.out.println(JSON.toJSONString(student)); } } class Stu2{ private List<String> id; public List<String> getId(){ return this.id != null ? this.id : new ArrayList<>(); } public void setId(List<String> ids){ this.id = ids; } } ``` 以上代码片段展示了如何通过辅助函数 `convertToMutable` 将潜在的不可变集合安全地转化为标准ArrayList实例[^3]。 #### 3. **注意事项** - 如果项目规模较大且依赖于旧版本FastJSON,请务必评估升级至最新稳定版的成本收益比; - 需要特别注意线程安全性问题,尤其是在高并发环境下频繁访问共享数据结构的情况下; - 推荐遵循《阿里巴巴Java编码规范》,合理构建线程池而不是滥用Executors工具类中的便捷工厂方法[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值