无限递归的构造器和javap使用指南

public class ConstructorRecursion {

ConstructorRecursion rc;

{

rc = newConstructorRecursion();

}

public ConstructorRecursion(){

System.out.println("noparameter constructor");

}

public static void main(String[] args){

ConstructorRecursion rc = new ConstructorRecursion();

}

}

Exceptionin thread "main" java.lang.StackOverflowError

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

at ConstructorRecursion.<init>(ConstructorRecursion.java:5)

表面上看,上面程序没有任何问题,ConstructorRecursion类的构造器中没有任何代码,只是单纯一句输出。但不要忘记了,不管是定义实例变量时指定的初始值,还是在非静态初始化块中执行的初始化操作,最终都将提取到构造器中执行。因为上面代码递归调用了ConstructorRecursion类的狗仔去哦,所以抛出了StackOverflowError错误。

这个程序给出的教训是:无论如何不要导致构造器产生递归调用。也就是说,应该:

尽量不要在定义实例变量时指定实例变量的值为当前类的实例;

尽量不要初始化块中创建当前类的实例;

尽量不要在构造器内调用本构造器创建Java对象;

C:\Documents andSettings\mz50947\workspace\TestProject\src>javap ConstructorRe

ursion

Compiled from"ConstructorRecursion.java"

public classConstructorRecursion extends java.lang.Object{

ConstructorRecursion rc;

public ConstructorRecursion();

public static voidmain(java.lang.String[]);

}

使用JAVAP可以查看java编译器生成的字节码,通过比较字节码和源代码,可以发现很多的问题。

C:\Documents andSettings\mz50947\workspace\TestProject\src>javac -g Constructor

Recursion.java

08/08/2013  02:50 PM               645 ConstructorRecursion.class

08/08/2013  02:34 PM               304 ConstructorRecursion.java

不带参数的javap将打印类的public信息,包括成员和方法。

C:\Documents andSettings\mz50947\workspace\TestProject\src>javap -c Constructor

Recursion

Compiled from"ConstructorRecursion.java"

public classConstructorRecursion extends java.lang.Object{

ConstructorRecursionrc;

publicConstructorRecursion();

Code:

0:  aload_0

1:  invokespecial   #1; //Methodjava/lang/Object."<init>":()V

4:  aload_0

5:  new     #2; //classConstructorRecursion

8:  dup

9:  invokespecial   #3; //Method"<init>":()V

12: putfield        #4; //Fieldrc:LConstructorRecursion;

15: getstatic       #5; //Fieldjava/lang/System.out:Ljava/io/PrintStream;

18: ldc     #6; //String no parameterconstructor

20: invokevirtual   #7; //Methodjava/io/PrintStream.println:(Ljava/lang/Str

ing;)V

23: return

public static voidmain(java.lang.String[]);

Code:

0:  new     #2; //classConstructorRecursion

3:  dup

4:   invokespecial  #3; //Method "<init>":()V

7:  astore_1

8:  return

}

C:\Documents andSettings\mz50947\workspace\TestProject\src>javap -l Constructor

Recursion

Compiled from"ConstructorRecursion.java"

public classConstructorRecursion extends java.lang.Object{

ConstructorRecursionrc;

publicConstructorRecursion();

LineNumberTable:

line 7: 0

line 5: 4

line 8: 15

line 9: 23

LocalVariableTable:

Start Length  Slot  Name  Signature

0     24      0    this      LConstructorRecursion;

public static voidmain(java.lang.String[]);

LineNumberTable:

line 11: 0

line 12: 8

LocalVariableTable:

Start Length  Slot  Name  Signature

0     9      0    args      [Ljava/lang/String;

8     1      1    rc      LConstructorRecursion;

}

C:\Documents andSettings\mz50947\workspace\TestProject\src>javap -c Constructor

Recursion

Compiled from"ConstructorRecursion.java"

public classConstructorRecursion extends java.lang.Object{

ConstructorRecursionrc;

public ConstructorRecursion();

Code:

0:  aload_0

1:  invokespecial   #1; //Methodjava/lang/Object."<init>":()V

4:  aload_0

5:  new     #2; //classConstructorRecursion

8:  dup

9:  invokespecial   #3; //Method"<init>":()V

12: putfield        #4; //Fieldrc:LConstructorRecursion;

15: getstatic       #5; //Fieldjava/lang/System.out:Ljava/io/PrintStream;

18: ldc     #6; //String no parameterconstructor

20: invokevirtual   #7; //Methodjava/io/PrintStream.println:(Ljava/lang/Str

ing;)V

23: return

public static voidmain(java.lang.String[]);

Code:

0:  new     #2; //classConstructorRecursion

3:  dup

4:  invokespecial   #3; //Method"<init>":()V

7:  astore_1

8:  return

}

The javap command iscalled the Java “disassembler”because it takes apart class files andtells you what’s inside them. You won’t use this command often, but using it tofind out how a particular Java statement works is fun, sometimes. You can alsouse it to find out what methods are available for a class if you don’t have thesource code that was used to create the class.

Here is the general format:

javapfilename [options]

The following is typical of the information you getwhen you run the javap command:

C:\java\samples>javapHelloApp

Compiledfrom "HelloApp.java"

publicclass HelloApp extends java.lang.Object{

public HelloApp();

public static voidmain(java.lang.String[]);

}

As you can see, the javap command indicates that the HelloApp class was compiled from the HelloApp.java file and that it consists of a HelloApppublic class and a mainpublic method.

You may want to use two options with the javap command. If you use the -c option, the javap command displays the actual Java bytecodes createdby the compiler for the class. (Java bytecode is the executable programcompiled from your Java source file.)

And if you use the -verbose option, the bytecodes — plus a ton of otherfascinating information about the innards of the class — are displayed. Here’sthe -c output for aclass named HelloApp:

C:\java\samples>javapHelloApp -c

Compiledfrom "HelloApp.java"

publicclass HelloApp extends java.lang.Object{

publicHelloApp();

Code:

0:  aload_0

1:  invokespecial   #1; //Method

java/lang/Object."<init>":()V

4:  return

publicstatic void main(java.lang.String[]);

Code:

0:  getstatic       #2; //Field

java/lang/System.out:Ljava/io/PrintStream;

3:  ldc     #3; //String Hello, World!

5:  invokevirtual   #4; //Method

java/io/PrintStream.println:(Ljava/lang/String;)V

8:  return

}

无限递归的构造器和javap使用指南的更多相关文章

  1. 无限“递归”的python程序

    如果一个函数直接或者间接调用了自己,那么就形成了递归(recursion),比如斐波那契数列的一个实现 def fib(n): if n <= 2: return 1 else: return ...

  2. 【整理】iview Tree数据格式问题,无限递归树处理数据

    iview Tree数据格式问题,无限递归树处理数据 https://juejin.im/post/5b51a8a4e51d455d6825be20

  3. -java转json hibernate懒加载造成的无限递归问题

    1.在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系. JoinColumn(name="pid") 2. 在保存数据时,总是先保存的 ...

  4. jackson java转json hibernate懒加载造成的无限递归问题

    @JsonIgnore @JsonFilter @JsonBackReference @JsonManagedReference @JsonIgnoreProperties jackson中的@Jso ...

  5. hibernate无限递归问题

    项目异常如下: 2018-01-26 17:12:38.162 WARN 3128 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionReso ...

  6. JPA一对多循环引用的解决&&JackSon无限递归问题

    说是解决,其实不是很完美的解决的,写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的,能否知道一二. 下面说说出现问题: 问题是这样的,当我查询一个一对多的实体的时候,工具直接就爆了,差不多我就 ...

  7. C# .NetCore简单实现无限递归的功能

    1:在实际开发中,我们会经常使用到无限递归的情况,如菜单,父子级等的情况 2:Code 1 using System; 2 using System.Collections.Generic; 3 us ...

  8. vue 无限递归级联组件实现方案

    最终组件效果图: 无限级联组件实现思想: 在这里有一个很重要的地方就是前端组件如何与后端匹配方法协调好,无限级联很好实现,但是如何让服务器端可以成功的匹配到条件是一个问题,在这里我借鉴了html元素的 ...

  9. SqlServer与Linq 无限递归目录树且输出层级

    ALTER VIEW [dbo].[view_TreeLevel] AS WITH cte AS ( SELECT a.ModuleID , a.Module_Name , a.Module_Desc ...

随机推荐

  1. java设计模式--创建模式--工厂方法

    工厂方法定义: 工厂方法 概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类.FactoryMethod使一个类的实例化延迟到其子类. 适用性 .当一个类不知道它所必须创建的对象的类的时候. ...

  2. zhihu spark集群,书籍,论文

    spark集群中的节点可以只处理自身独立数据库里的数据,然后汇总吗? 修改 我将spark搭建在两台机器上,其中一台既是master又是slave,另一台是slave,两台机器上均装有独立的mongo ...

  3. HTML5学习摘录

    设计原理 不是规范里都包含什么,而是规范里为什么会包含它们,以及在设计这个规范的时候,设计者们是怎么看待这些东西的. 发展史:HTML2.0——>HTML3.2——>HTML4.0.1—— ...

  4. ntp服务器池列表

    CentOS: 0.centos.pool.ntp.org 1.centos.pool.ntp.org 2.centos.pool.ntp.org 国内可用的 ntp.fudan.edu.cn 复旦 ...

  5. UGUI Text控件

    学习UGUI的Text控件,用于显示文本!.  基本属性就不再啰嗦了! Alignment: 文字以 水平和垂直 对齐方式, Horizontal Overflow: 水平 Wrap: 文字大小和数量 ...

  6. Windows Message Queue(优先队列)

    欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) Windows Message Queue Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  7. Int16 Int32 Int64

    数据类型占多大空间 Int16, 等于short, 占2个字节. -32768 32767 Int32, 等于int, 占4个字节. -2147483648 2147483647 Int64, 等于l ...

  8. android XML解析之DOM解析方式

    DOM 解析方式步骤: 第一步:首选需要获得DOM解析器工厂实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ...

  9. JQ 复制节点

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. CAShapeLayer + UIBezierPath

    UIBezierPath: UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径.使用此类可以定义常见的圆形.多边形等形状 .我们使用直线.弧(arc) ...