已解决【CodeGenerationException: java.lang.NoSuchMethodException-->$xx$$EnhancerByCGLIB$$xx.<init>(xx)】

本文通过一个项目场景探讨了使用Cglib对FileWriter和BufferedWriter的close方法进行代理,以研究try-with-resource自动关闭资源的顺序。在尝试创建代理对象时,由于构造方法匹配问题导致异常。经过分析,发现构造器参数类型应与实际参数类型一致,而非其子类。修复此问题后,确保了代理对象的正确创建并能正确关闭资源。

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

项目场景:

准备使用使用Cglib对FileWrite、BufferedWriter的close进行代理,以研究try-with-resource自动关闭资源的先后顺序。


问题描述

写了如下代码:

  • 因为需要代理对象,因此需要创建FileWriter 、BufferedWriter 对象;一旦创建要关闭,因此使用了try-with-resource自动关闭
  • 分别对FileWriter 、BufferedWriter的close方法做增强
  • 内层嵌套try-with-resource创建代理对象,以检验谁先被关闭
try (FileWriter fileWriter = new FileWriter("fw.txt");
     BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
    // 代理FileWriter的close方法
    Enhancer fwEnhancer = new Enhancer();
    fwEnhancer.setSuperclass(FileWriter.class);
    fwEnhancer.setCallback(new MethodInterceptor() {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            if ("close".equals(method.getName())) {
                System.out.println("fw  close...");
            }
            return method.invoke(fileWriter, objects);
        }
    });


    // 代理BufferedWriter的close方法
    Enhancer bwEnhancer = new Enhancer();
    bwEnhancer.setSuperclass(BufferedWriter.class);
    bwEnhancer.setCallback(new MethodInterceptor() {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            if ("close".equals(method.getName())) {
                System.out.println("bw  close...");
            }
            return method.invoke(bufferedWriter, objects);
        }
    });


    //检验谁先被关闭
    try (
    	FileWriter myFw = 
    		(FileWriter) fwEnhancer.create(new Class[]{String.class}, new String[]{"fr.txt"});
        BufferedWriter myBw = 
        	(BufferedWriter) bwEnhancer.create(new Class[]{FileWriter.class}, new FileWriter[]{myFw})
        )  {
        //...
    }
} catch (IOException e) {
    e.printStackTrace();
}
    

结果报异常:
在这里插入图片描述

异常位置位于:
BufferedWriter myBw = (BufferedWriter) bwEnhancer.create(new Class[]{FileWriter.class}, new FileWriter[]{myFw})


原因分析:

原因大概说没有这样的构造方法,去看一眼:
在这里插入图片描述
有一个构造函数,需要Writer.class,但我传的是它的子类:FileWriter.class


解决方案:

构造器是什么类型,new class就写什么类型;
将如下代码:

BufferedWriter myBw = (BufferedWriter) bwEnhancer.create(
	new Class[]{FileWriter.class}, 
	new FileWriter[]{myFw}
)

改成:

BufferedWriter myBw = (BufferedWriter) bwEnhancer.create(
	new Class[]{Writer.class}, 
	new FileWriter[]{myFw}
)

总结:

  • 构造器里面要什么,Class数组里面就写什么,写它的子类也不行
  • 参数类型是啥写啥,具体的参数可以写其子类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值