Java 动态代理Object对象转为接口报错问题

本文深入探讨Java动态代理的实现机制,解析动态代理对象创建过程中的常见错误及其解决方案,特别是针对接口转换异常的具体修正方法。

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

public interface Subject {
	public void shopping();
}
public class Person implements Subject{

    @Override
    public void shopping() {
        System.out.println("Pay for the good!");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class CreateProxy implements InvocationHandler {
	private Object target;
	public Object create(Object target) {
		//生成代理对象
		this.target = target;
		Object xx  = Proxy.newProxyInstance(this.getClass().getClassLoader(),
				this.getClass().getInterfaces(),this);
		return xx;
		
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		method.invoke(target, args);
		System.out.println("Pay successfully!");
		return null;
	}

}
import org.junit.jupiter.api.Test;

class ProxyTest {

	@Test
	public void test() {
		CreateProxy cp = new CreateProxy();
		Subject person = new Person();
		Object proxy = cp.create(person);
		Subject xxx = (Subject)proxy;
		xxx.shopping();
	}

}

报错:java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to dynamicProxy.Subject

           生成的动态代理对象不能转成dynamicProxy包下的Subject接口

            操作环境是JDK10,eclipse IDE

百度了好久,一开始觉得是Object对象是父类转成Interface接口子类 有问题但不是

其实是Proxy.newProxyInstance生成动态代理对象有问题

对应的newProxyInstance方法newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h

参数:loader - 类加载器来定义代理类     interfaces - 代理类实现的接口列表     h - 调度方法调用的调用处理函数

上面代码中interfaces参数传入的有问题

解决办法:

interfaces参数改为new Class[]{dynamicProxy.Subject.class}

### java.lang.UnsupportedOperationException 报错原因 `java.lang.UnsupportedOperationException` 是 Java 中的一种运行时异常,当试图执行某个未被支持的操作时会抛出此异常。它通常发生在集合框架中,尤其是对于不可变集合或者某些特定实现的集合对象。 #### 原因分析 1. **不可变集合操作** 当尝试对通过 `Collections.unmodifiableList()` 或其他类似方法创建的只读集合进行修改操作(如 `add`, `remove` 等),就会触发该异常[^1]。 2. **Arrays.asList 的局限性** 使用 `Arrays.asList()` 方法转换数组为 List 后,默认返回的 List 实现并不完全支持动态调整大小的操作。例如,`add` 和 `remove` 方法可能会引发 `UnsupportedOperationException` 异常[^2]。 3. **迭代器移除限制** 如果使用的集合实现了 `AbstractList` 类,并且其子类没有覆盖 `Iterator.remove()` 方法,则在使用迭代器删除元素时也会抛出此异常[^3]。 --- ### 解决方案 针对不同场景下的 `java.lang.UnsupportedOperationException`,可以采取以下措施: #### 场景一:不可变集合 如果需要对一个不可变集合进行修改操作,可以通过将其转化为可变集合来解决问题。例如: ```java // 将不可变集合转为可变集合 List<String> unmodifiableList = Collections.unmodifiableList(Arrays.asList("A", "B")); List<String> modifiableList = new ArrayList<>(unmodifiableList); modifiableList.add("C"); // 正确操作 ``` #### 场景二:Arrays.asList 局限性 由于 `Arrays.asList()` 返回的列表具有固定大小,因此无法直接调用 `add` 或 `remove` 方法。解决办法是将其封装到一个支持动态扩展的集合中,比如 `ArrayList`: ```java String[] array = {"A", "B"}; List<String> fixedSizeList = Arrays.asList(array); // 转化为支持动态扩展的列表 List<String> dynamicList = new ArrayList<>(fixedSizeList); dynamicList.add("C"); // 不再抛出异常 ``` #### 场景三:迭代器移除限制 部分集合的默认实现可能并未提供完整的 `Iterator.remove()` 支持。此时应确保所使用的集合类型确实支持这一功能。例如,在处理由 `Arrays.asList()` 得到的列表时,需注意这一点[^4]: ```java Collection<Object> collection = new ArrayList<>(Arrays.asList(123, 456, "Tom", false)); Iterator<Object> iterator = collection.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); if ("Tom".equals(obj)) { iterator.remove(); // 安全移除 } } ``` #### 场景四:MyBatis 查询配置错误 在 MyBatis 开发过程中,若返回的结果集与预期不符也可能导致此类异常。例如,将 XML 文件中的返回类型设置为整个 `List` 对象而非其中的具体元素类型时会出现问题。正确的做法是按照实际需求指定合适的返回类型[^5]: - 若返回值为简单类型(如 `int`, `String`),则应在 `<select>` 标签中设置对应的 `resultType`; - 若返回值是一个复杂类型的集合,则应指明集合内的元素类型。 --- ### 总结 `java.lang.UnsupportedOperationException` 主要源于对不支持的操作进行了非法调用。无论是集合框架还是第三方库(如 MyBatis),都需要仔细阅读文档并理解其实现细节以规避潜在风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值