【错误记录】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()
目录
相关文章
|
4月前
|
存储 算法 Java
惊!Java程序员必看:JVM调优揭秘,堆溢出、栈溢出如何巧妙化解?
【8月更文挑战第29天】在Java领域,JVM是代码运行的基础,但需适当调优以发挥最佳性能。本文探讨了JVM中常见的堆溢出和栈溢出问题及其解决方法。堆溢出发生在堆空间不足时,可通过增加堆空间、优化代码及释放对象解决;栈溢出则因递归调用过深或线程过多引起,调整栈大小、优化算法和使用线程池可有效应对。通过合理配置和调优JVM,可确保Java应用稳定高效运行。
149 4
|
19天前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
46 5
|
1月前
|
存储 算法 Java
🧠Java零基础 - Java栈(Stack)详解
【10月更文挑战第17天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
34 2
|
2月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
29 1
|
3月前
|
Java
java基础(11)函数重载以及函数递归求和
Java支持函数重载,即在同一个类中可以声明多个同名方法,只要它们的参数类型和个数不同。函数重载与修饰符、返回值无关,但与参数的类型、个数、顺序有关。此外,文中还展示了如何使用递归方法`sum`来计算两个数之间的和,递归的终止条件是当第一个参数大于第二个参数时。
34 1
java基础(11)函数重载以及函数递归求和
|
2月前
|
Java 编译器 C语言
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
29 3
|
2月前
|
存储 安全 Java
【用Java学习数据结构系列】探索栈和队列的无尽秘密
【用Java学习数据结构系列】探索栈和队列的无尽秘密
35 2
|
4月前
|
Java 索引
java中的栈(利用数组实现栈)
这篇文章通过Java代码示例介绍了如何使用数组实现栈操作,包括栈的初始化、入栈、出栈、判断栈满和空以及遍历栈的方法。
java中的栈(利用数组实现栈)
|
4月前
|
Java 调度 Android开发
Android经典实战之Kotlin的delay函数和Java中的Thread.sleep有什么不同?
本文介绍了 Kotlin 中的 `delay` 函数与 Java 中 `Thread.sleep` 方法的区别。两者均可暂停代码执行,但 `delay` 适用于协程,非阻塞且高效;`Thread.sleep` 则阻塞当前线程。理解这些差异有助于提高程序效率与可读性。
85 1
|
5月前
|
存储 Java 编译器
Java中ArrayList的常用函数
确切地说,`ArrayList` 提供的这些方法构成了一套强大并且灵活的工具集,可以满足各种程序设计情况中的需求。例如,通过使用 `iterator()`方法,开发者可以在不知道集合大小的情况下遍历集合中全部或部分元素;而 `sort()`方法则能够对集合中的元素进行排序。这些函数在日常的Java编程中极其常见且重要,掌握它们对于进行集合操作和数据处理来说是基础且必须的。
37 2
Java中ArrayList的常用函数