【错误记录】Groovy 函数拦截调用 invokeMethod 导致栈溢出 ( java.lang.StackOverflowError )

简介: 【错误记录】Groovy 函数拦截调用 invokeMethod 导致栈溢出 ( java.lang.StackOverflowError )

文章目录

一、报错信息

二、解决方案





一、报错信息


使用 Groovy 函数拦截功能 , 定义 Groovy 类 , 实现 GroovyInterceptable 接口 , 并重写 invokeMethod 方法 , 在该方法中使用


println "invokeMethod"


代码 , 打印日志 ;


完整代码如下 :


class Student implements GroovyInterceptable{
    def name;
    def hello() {
        println "Hello ${name}"
    }
    @Override
    Object invokeMethod(String name, Object args) {
        println "invokeMethod"
        //System.out.println "invokeMethod"
    }
}
def student = new Student(name: "Tom")
// 直接调用 hello 方法
student.hello()


报错信息 :


Caught: java.lang.StackOverflowError
java.lang.StackOverflowError
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)
  at Student.invokeMethod(Groovy.groovy:10)


image.png



二、解决方案


调用 实现了 GroovyInterceptable 接口的 Student 类的 hello 方法 , 会调用 invokeMethod 方法 ,


在 invokeMethod 方法中 , 又调用了 println 方法 ,


 

@Override
    Object invokeMethod(String name, Object args) {
        println "invokeMethod"
        //System.out.println "invokeMethod"
    }


println 方法是 Groovy 注入到 Object 对象中的 , 在 Student 对象中 , 调用 println 也会回调 invokeMethod 方法 , 而在 invokeMethod 方法中又调用了 println 方法 , 这样循环调用 , 最终导致栈溢出 ;


在 invokeMethod 中 , 不调用 println 方法 , 调用 System.out.println 进行日志打印 , 这样就可以避免栈溢出 ;


class Student implements GroovyInterceptable{
    def name;
    def hello() {
        println "Hello ${name}"
    }
    @Override
    Object invokeMethod(String name, Object args) {
        System.out.println "invokeMethod"
    }
}
def student = new Student(name: "Tom")
// 直接调用 hello 方法
student.hello()
目录
相关文章
|
17天前
|
Java 开发者
Java一分钟之-Groovy与Java混合编程
【6月更文挑战第13天】本文探讨了Groovy与Java的混合编程,强调了Groovy在JVM上的动态特性及其与Java的高兼容性。文章指出,尽管二者可无缝共存,但仍存在类型不匹配、闭包与匿名内部类差异及语法糖导致的问题。为避免这些问题,建议在Groovy中显式指定类型、理解闭包与匿名类的区别,并制定统一编码规范。通过实例展示了Java调用Groovy脚本和Groovy调用Java类的方法,强调理解两种语言特性的重要性,以实现更高效、维护性更强的系统。
42 3
Java一分钟之-Groovy与Java混合编程
|
4天前
|
Java
java堆溢出和栈溢出
java堆溢出和栈溢出
9 1
|
6天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
18 2
|
7天前
|
网络协议 Java 程序员
TCP/IP协议栈是网络通信基础,Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用
【6月更文挑战第23天】 **TCP/IP协议栈是网络通信基础,它包含应用层(HTTP, FTP等)、传输层(TCP, UDP)、网络层(IP)、数据链路层(帧, MAC地址)和物理层(硬件信号)。Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用,如Socket和ServerSocket用于客户端和服务器通信。**
20 3
|
6天前
|
Java
轻松入门Java中的Lambda函数
轻松入门Java中的Lambda函数
|
9天前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
15 1
|
10天前
|
Java
杨老师课堂_Java教程第五篇之函数运用
杨老师课堂_Java教程第五篇之函数运用
12 1
|
11天前
|
算法 Java C语言
Java中的算法与C语言中的函数
Java中的算法与C语言中的函数
11 2
|
13天前
|
存储 Java 开发者
【Java】Java中栈溢出的常见情况
【Java】Java中栈溢出的常见情况
13 4
|
1天前
|
Java 测试技术
在Java中使用断言函数进行代码测试
在Java中使用断言函数进行代码测试