Class类(java.lang.Class)

本文介绍了Java反射机制的基本概念,包括Class对象的实例化方式及newInstance方法的使用,并通过示例展示了如何利用反射创建对象。

构造方法

public final class Class<T>extendsObjectimplements Serializable, GenericDeclaration, Type, AnnotatedElement

Class对象的三种实例化模式

1.        对象.getClass();

2.        类.class;

3.        Class.forName(String className)

public static Class<?> forName(String className)  throws ClassNotFoundException

Class类对象(类)的实例化形式

Class类的对象.newInstance(); 
 public T newInstance()throws InstantiationException,  IllegalAccessException

反射的一般实例:

class Phone {
	public Phone() {
		System.out.println("Phone类的构造方法");
	}
	public String toString() {
		return "是一部手机";
	}
}
public class Test {
	public static void main(String[] args) throws Exception {
		Class<Phone> cls = Phone.class;
		Phone p2 =  cls.newInstance();
		System.out.println("p2: " + p2);
	}
}


















<think>我们正在解决一个特定的问题:在使用Gson序列化时,尝试序列化`java.lang.Class`型的对象(例如`String.class`)导致`UnsupportedOperationException`,并提示"Forgot to register a type adapter?"。 根据引用[1][2][3][4],我们可以知道: - Gson默认不支持序列化`java.lang.Class`对象。 - 错误信息明确提示需要注册一个型适配器(Type Adapter)来处理`Class`型。 ### 问题原因 Gson在序列化过程中遇到`Class`对象(如`String.class`)时,由于没有内置的`TypeAdapter`来处理`java.lang.Class`型,因此会抛出`UnsupportedOperationException`。 ### 解决方案 #### 方案1:避免序列化Class对象(推荐) 如果可能,修改代码结构,避免将`Class`对象放入需要序列化的数据结构中。例如,改为序列化名字符串: ```java // 错误示例:直接序列化Class对象 Map<String, Object> data = new HashMap<>(); data.put("classType", String.class); // 正确示例:序列化名 data.put("className", String.class.getName()); ``` #### 方案2:为Class型注册自定义TypeAdapter 如果必须序列化`Class`对象,可以创建一个`TypeAdapter`来处理`Class`型的序列化和反序列化,然后将其注册到Gson实例中。 **步骤1:创建Class型适配器** ```java import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; public class ClassTypeAdapter extends TypeAdapter<Class<?>> { @Override public void write(JsonWriter out, Class<?> value) throws IOException { if (value == null) { out.nullValue(); } else { // 将Class序列化为它的全限定名 out.value(value.getName()); } } @Override public Class<?> read(JsonReader in) throws IOException { try { String className = in.nextString(); // 根据名加载Class return Class.forName(className); } catch (ClassNotFoundException e) { throw new IOException(e); } } } ``` **步骤2:注册适配器并使用Gson** ```java Gson gson = new GsonBuilder() .registerTypeAdapter(Class.class, new ClassTypeAdapter()) .create(); // 现在可以序列化Class对象了 String json = gson.toJson(String.class); System.out.println(json); // 输出: "java.lang.String" // 反序列化 Class<?> clazz = gson.fromJson("\"java.lang.String\"", Class.class); System.out.println(clazz); // 输出: class java.lang.String ``` #### 方案3:使用现有库(如Hibernate代理处理) 如果问题涉及Hibernate代理(如引用[1][4]),可以使用专门为Hibernate代理设计的适配器。例如,注册`HibernateProxyTypeAdapter`: ```java Gson gson = new GsonBuilder() .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) .create(); ``` ### 总结 | 情况 | 解决方案 | |------|----------| | 可以避免序列化Class | 使用名字符串代替Class对象 | | 必须序列化Class对象 | 注册自定义`ClassTypeAdapter` | | 涉及Hibernate代理 | 注册Hibernate代理适配器工厂 | > 关键点:Gson默认不支持序列化`Class`对象,必须通过自定义适配器实现[^3][^4]。 ### 相关问题 1. 如何为Gson自定义其他特殊型的适配器(如`java.time.LocalDateTime`)? 2. 使用Gson序列化Hibernate实体时如何避免代理异常? 3. Gson中如何统一处理所有型的序列化异常?</think>### 解决 Gson 序列化 `java.lang.Class` 的 `UnsupportedOperationException` #### 问题根源 当 Gson 尝试序列化 `java.lang.Class` 对象(如 `String.class`)时,会触发此异常,因为 **Gson 默认不支持直接序列化 `Class` 型**。错误信息中的 `Forgot to register a type adapter?` 明确指出了解决方案方向[^1][^3]。 --- ### 三种解决方案 #### 方案 1:避免序列化 Class 对象(推荐) **将 `Class` 对象转换为名字符串**: ```java // 错误:直接序列化 Class 对象 gson.toJson(String.class); // 正确:序列化名 gson.toJson(String.class.getName()); // 输出 "java.lang.String" ``` 在需要还原时: ```java Class<?> clazz = Class.forName(gson.fromJson(jsonString, String.class)); ``` #### 方案 2:注册全局 Class 型适配器 创建自定义 `TypeAdapter` 处理 `Class` 序列化: ```java public class ClassTypeAdapter extends TypeAdapter<Class<?>> { @Override public void write(JsonWriter out, Class<?> value) throws IOException { if (value == null) { out.nullValue(); } else { // 将 Class 序列化为名字符串 out.value(value.getName()); } } @Override public Class<?> read(JsonReader in) throws IOException { try { return Class.forName(in.nextString()); } catch (ClassNotFoundException e) { throw new JsonIOException(e); } } } ``` 注册到 Gson 实例: ```java Gson gson = new GsonBuilder() .registerTypeAdapter(Class.class, new ClassTypeAdapter()) .create(); // 现在可安全序列化 Class 对象 String json = gson.toJson(String.class); // 输出 "java.lang.String" ``` #### 方案 3:使用 Hibernate 代理适配器(针对 Hibernate 实体) 若涉及 Hibernate 代理对象(如引用[1][4]),需特殊处理: ```java Gson gson = new GsonBuilder() .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) // 添加 Hibernate 适配器 .create(); ``` --- ### 关键点总结 | **场景** | **解决方案** | **适用性** | |------------------------------|------------------------------------------|--------------------| | 序列化 `String.class` 等对象 | 使用名替代:`String.class.getName()` | 通用推荐方案 | | 必须保留 Class 型 | 注册全局 `ClassTypeAdapter` | 需要型还原时 | | Hibernate 代理实体 | 添加 `HibernateProxyTypeAdapter.FACTORY` | Hibernate 项目专用 | > **原理**:Gson 的默认适配器 `TypeAdapters$1` 仅支持基础型,遇到 `Class` 对象时会抛出 `UnsupportedOperationException`[^3]。通过自定义适配器,将 `Class` 映射为字符串可安全序列化。 --- ### 调试建议 1. **定位问题代码**: ```java // 堆栈中关键行指向的代码 at com.jk.moinc.framework.utils.GsonUtil.toJson(GsonUtil.java:31) ``` 2. **检查序列化对象**: ```java // 打印对象结构,查找 Class 型字段 System.out.println("Serialized object: " + objectToSerialize.getClass().getDeclaredFields()); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值