【错误记录】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()
目录
相关文章
|
6月前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
179 4
|
存储 算法 Java
惊!Java程序员必看:JVM调优揭秘,堆溢出、栈溢出如何巧妙化解?
【8月更文挑战第29天】在Java领域,JVM是代码运行的基础,但需适当调优以发挥最佳性能。本文探讨了JVM中常见的堆溢出和栈溢出问题及其解决方法。堆溢出发生在堆空间不足时,可通过增加堆空间、优化代码及释放对象解决;栈溢出则因递归调用过深或线程过多引起,调整栈大小、优化算法和使用线程池可有效应对。通过合理配置和调优JVM,可确保Java应用稳定高效运行。
499 4
|
存储 IDE Java
java设置栈内存大小
在Java应用中合理设置栈内存大小是确保程序稳定性和性能的重要措施。通过JVM参数 `-Xss`,可以灵活调整栈内存大小,以适应不同的应用场景。本文介绍了设置栈内存大小的方法、应用场景和注意事项,希望能帮助开发者更好地管理Java应用的内存资源。
718 4
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
364 5
|
Java
java基础(11)函数重载以及函数递归求和
Java支持函数重载,即在同一个类中可以声明多个同名方法,只要它们的参数类型和个数不同。函数重载与修饰符、返回值无关,但与参数的类型、个数、顺序有关。此外,文中还展示了如何使用递归方法`sum`来计算两个数之间的和,递归的终止条件是当第一个参数大于第二个参数时。
137 1
java基础(11)函数重载以及函数递归求和
|
存储 算法 Java
🧠Java零基础 - Java栈(Stack)详解
【10月更文挑战第17天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
524 2
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
160 1
|
Java 编译器 C语言
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
217 3
|
存储 安全 Java
【用Java学习数据结构系列】探索栈和队列的无尽秘密
【用Java学习数据结构系列】探索栈和队列的无尽秘密
172 2
|
Java 索引
java中的栈(利用数组实现栈)
这篇文章通过Java代码示例介绍了如何使用数组实现栈操作,包括栈的初始化、入栈、出栈、判断栈满和空以及遍历栈的方法。
java中的栈(利用数组实现栈)