Java StackOverflowError详解

StackOverflowError

原因 : 函数调用栈太深了,注意代码中是否有了循环调用方法而无法退出的情况

原理

StackOverflowError 是一个java中常出现的错误:在jvm运行时的数据区域中有一个java虚拟机栈,当执行java方法时会进行压栈弹栈的操作。在栈中会保存局部变量,操作数栈,方法出口等等。jvm规定了栈的最大深度,当执行时栈的深度大于了规定的深度,就会抛出StackOverflowError错误。

典型的例子:

public class StackOverFlowDemo {

    public static void Foo(){
        Foo();
    }

    public static void main(String[] args) {
        Foo();
    }
}

今天我遇见了另外一种情况:当两个对象相互引用,在调用toString方法时会产生这个异常,因为它们会循环调用toString方法。

//book和student相互循环引用
public class StackOverFlowDemo {

    static class Student{
        String name;
        Book book;

        public Student(String name) {
            this.name = name;
        }
        //循环调用toString方法
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", book=" + book +
                    '}';
        }
    }

    static class Book {
        String isbn;
        Student student;

        public Book(String isbn, Student student) {
            this.isbn = isbn;
            this.student = student;
        }

        @Override
        public String toString() {
            return "Book{" +
                    "isbn='" + isbn + '\'' +
                    ", student=" + student +
                    '}';
        }
    }

    public static void main(String[] args) {
        Student student=new Student("zhang3");
        Book book=new Book("1111",student);
        student.book=book;
        System.out.println(book.toString());
    }

}

出现的错误:

toString()

说到toString()方法,在打印一个对象时,会先调用这个对象的toString()方法,例如:

public class toStringDemo {

    static class A{
        @Override
        public String toString() {
            System.out.print("I ");
            return "";
        }
    }

    public static void main(String[] args) {
        A a=new A();
        System.out.println("love you."+a);
    }
}

会输出:

I love you.

到此这篇关于Java StackOverflowError详解的文章就介绍到这了,更多相关Java StackOverflowError内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 高精度的大数字运算方式

    目录 Java 高精度的大数字运算 高精度整数BigInteger 高精度浮点数BigDecimal (1)BigInteger和BigDecimal都是不可变(immutable) (2)BigDecimal有4个够造方法 (3)equals()方法认为0.1和0.1是相等的 (4)另外还有一些情形 java超长数据高精度计算(仅支持整数) Java 高精度的大数字运算 为了解决Java基本数据类型在运算时会出现的溢出和计算不精确的问题.Java 提供了两个类BigInteger和BigDec

  • Java BigDecimal除法精度和格式化输出方式

    目录 BigDecimal除法精度和格式化输出 答案 BigDecimal的用法详解 保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理 构造器描述 方法描述 常用方法 BigDecimal除法精度和格式化输出 import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.text.DecimalFormat; public class

  • Java ResultSet案例讲解

    ResultSet ResultSet是我们使用jdbc连接时,查询的一个返回结果集,ResultSet resultSet = stmt.executeQuery(sql),下面就使用例子介绍ResultSet的使用 例子是通过jdbc连接查account表中的数据,然后用实体类Account封装起来,返回这个类的集合.  jdbc工具类代码 package com.lingaolu.Utils; import java.io.FileReader; import java.io.IOExce

  • Java DFA算法案例详解

    1.背景 项目中需要对敏感词做一个过滤,首先有几个方案可以选择: 直接将敏感词组织成String后,利用indexOf方法来查询. 传统的敏感词入库后SQL查询. 利用Lucene建立分词索引来查询. 利用DFA算法来进行. 首先,项目收集到的敏感词有几千条,使用a方案肯定不行.其次,为了方便以后的扩展性尽量减少对数据库的依赖,所以放弃b方案.然后Lucene本身作为本地索引,敏感词增加后需要触发更新索引,并且这里本着轻量原则不想引入更多的库,所以放弃c方案.于是我们选定d方案为研究目标. 2.

  • JavaScript实现更换头像功能

    本文实例为大家分享了JavaScript实现更换头像功能的具体代码,供大家参考,具体内容如下 最主要的是使用jquery的插件 cropper 1.基本使用步骤 1.在 <head> 中导入 cropper.css 样式表: <link rel="stylesheet" href="/assets/lib/cropper/cropper.css" /> 2.在 <body> 的结束标签之前,按顺序导入如下的 js 脚本: <

  • java中求高精度除法,要求保留N位小数

    目录 求高精度除法,要求保留N位小数 题目要求 java 大数处理和高精度小数处理(so easy) 简单的例子: 部分简单代码 求高精度除法,要求保留N位小数 题目要求 高精度除法,要求保留N位小数(四舍五入),并且当整数部分为0时去除0的显示 import java.math.BigDecimal; import java.util.Scanner; public class BD { public static void main(String[] args) { Scanner scan

  • Java sdk安装及配置案例详解

    1.安装Java SDK开发环境. 首先去官网下载Java SDK,http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html, 下载完成之后,开始安装. 点击下一步,安装完成. 2.配置Java SDK环境变量 单击"计算机-属性-高级系统设置",单击"环境变量".在"系统变量"栏下单击"新建",创建新的系统环境变量.

  • 聊聊Java BigInteger里面的mod和remainder的区别

    目录 BigInteger里的mod和remainder区别 mod是模运算,remainder是求余运算 BigInteger类的一些使用心得 下面总结一下以后方便找 1.给大数赋值 2.把int型转化为string型 3.把两个字符串拼接 BigInteger里的mod和remainder区别 下面直接上图吧,稍后解释关于mod和remainder以及负数求余求模的区别. mod是模运算,remainder是求余运算 如果被除数是正整数,mod和remainder的结果没区别.mod运算除数

  • Java StackOverflowError详解

    StackOverflowError 原因 : 函数调用栈太深了,注意代码中是否有了循环调用方法而无法退出的情况 原理 StackOverflowError 是一个java中常出现的错误:在jvm运行时的数据区域中有一个java虚拟机栈,当执行java方法时会进行压栈弹栈的操作.在栈中会保存局部变量,操作数栈,方法出口等等.jvm规定了栈的最大深度,当执行时栈的深度大于了规定的深度,就会抛出StackOverflowError错误. 典型的例子: public class StackOverFl

  • Java BigDecimal详解_动力节点Java学院整理

    1.引言 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,例如银行存款数额,这时候BigDecimal就派上大用场啦. 2.BigDecimal简介 BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组

  • Java递归算法详解(动力节点整理)

    递归算法是一种直接或者间接调用自身函数或者方法的算法.Java递归算法是基于Java语言实现的递归算法.递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解.递归算法对解决一大类问题很有效,它可以使算法简洁和易于理解.    递归算法解决问题的特点: 1)递归就是方法里调用自身.  2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口.  3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低.所以一般不提倡用递归算法设计程序.  4)在递

  • Java 匿名内部类详解及实例代码

    Java  匿名内部类详解 匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 实例1:不使用匿名内部类来实现抽象方法 abstract class Person { public abstract void eat(); } class Child extends Person { public void eat() { System.out.println("eat someth

  • Java设计模式详解之门面模式(外观模式)

    门面模式(Facade Pattern)也叫外观模式,它隐藏系统的复杂性,并向客户端提供一个可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性,为子系统中的一组接口提供了一个统一的高层访问接口,这个接口使得子系统更容易被访问或使用.这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用. 简而言之,就是把一堆复杂的流程封装成一个接口供给用户更简单的使用,这个设计模式里有三个角色: 1)门面角色( facade ):

  • Java Cache详解及简单实现

     Java Cache详解及简单实现 概要: 最近在做spring的项目,想做一个缓存,访问数据库,定期来做数据更新 要实现两个功能 可以通过http请求来立刻刷新缓存 缓存可以通过自己配置的时间间隔来定期刷新 通过Controller来做 因为需要通过http来刷新缓存,所以第一个想法就是把缓存做成一个Controller Controller的实现 Controller最大的优势,就是可以通过Spring的配置,注入很多依赖,比如对Service的依赖,对数据库的依赖等. 大量的访问数据库跟

  • java 二分法详解几种实现方法

    java 二分法详解几种方法 二分查找(java实现) 二分查找 算法思想:又叫折半查找,要求待查找的序列有序.每次取中间位置的值与待查关键字比较,如果中间位置的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,则在后半部分循环这个查找的过程.直到查找到了为止,否则序列中没有待查的关键字. 实现: 1.非递归代码 public static int biSearch(int []array,int a){ int lo=0; int hi=array.length

  • JAVA 注解详解及简单实例

    JAVA 注解详解及简单实例 何为注解 注解(Annotation)又称为元数据,在JDK1.5后引入,它的作用是: 生成文档  这是注解的原始用途,可以通过注解生成JavaDoc文档 跟踪代码的依赖性  可以通过注解替代配置文件,简化项目的配置.现有的许多框架都采用这个功能减少自己的配置. 编译检查  在编译时进行格式检查,例如@Override 基础注解 Java目前内置了三种标准注解,以及四种元注解.四种元注解负责创建其他的注解. 三种标准注解 @Override,表示当前的方法覆盖超类中

  • Python 调用Java实例详解

    Python 调用Java实例详解 前言: Python 对服务器端编程不如Java 所以这方面可能要调用Java代码 前提: Linux 环境  1 安装 jpype1 安装后测试代码: from jpype import * startJVM(getDefaultJVMPath(), "-ea") java.lang.System.out.println("Hello World") shutdownJVM() 2 调用非jdk的jar包, test.jar 包

  • java 线程详解及线程与进程的区别

    java  线程详解及线程与进程的区别 1.进程与线程 每个进程都独享一块内存空间,一个应用程序可以同时启动多个进程.比如IE浏览器,打开一个Ie浏览器就相当于启动了一个进程. 线程指进程中的一个执行流程,一个进程可以包含多个线程. 每个进程都需要操作系统为其分配独立的内存空间,而同一个进程中的多个线程共享这块空间,即共享内存等资源. 每次调用java.exe的时候,操作系统都会启动一个Java虚拟机进程,当启动Java虚拟机进程时候,Java虚拟机都会创建一个主线程,该线程会从程序入口main

随机推荐