无限递归的构造器和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. Eclipse中设置注释、日期等信息

    在使用Eclipse 编写Java代码时,自动生成的注释信息都是按照预先设置好的格式生成的,例如其中author,datetime等属性值. 我们可以在Eclipse 中进行设置自己希望显示的注释信息 ...

  2. JS Message 网页消息提醒

    JS message是一个非常小的(用gzip压缩之后才3kb)JavaScript library 用于轻松在网页上展示通知提醒.除了通知,它还支持创建带风格的对话框和确认对话框.不需要任何JS框架 ...

  3. Python load json file with UTF-8 BOM header - Stack Overflow

    Python load json file with UTF-8 BOM header - Stack Overflow 3 down vote Since json.load(stream) use ...

  4. 在php添加mongo过程中出现的mongo.so: > undefined symbol: php_json_encode in Unknown on line 0. After installation mongo driver for php 的错误

    3 down vote my system is centos 6.3. I got the problem solved. vim /etc/php.ini then add extension=j ...

  5. IOS 排序算法

    /** * @brief 冒泡排序法 * * @param arr 需要排序的数组 */ -(void)BubbleSort:(NSMutableArray *)arr { // 取第一个与其邻接的对 ...

  6. [Redux] Generating Containers with connect() from React Redux (AddTodo)

    Code to be refacted: const AddTodo = (props, { store }) => { let input; return ( <div> < ...

  7. Model注解的后台原理

    Asp.net MVC的验证特性是由模型绑定器.模型元数据.模型验证器和模型状态组成的协调系统的一部分. 1.验证和模型绑定 默认情况下,Asp.net MVC框架在模型绑定石执行验证逻辑,在操作方法 ...

  8. Swift语法基础入门一(适合有C, OC开发人员)

    Swift开发体验 /*: 创建对象 * OC: alloc initWithXXX 方法 * Swift: (xxx:) */ /*: 调用方法 * OC: [UIColor redColor]; ...

  9. Java枚举类enum

    枚举类enum是JDK1.5引入的,之前都是用public static final int enum_value来代替枚举类的.枚举类enum是一种特殊的类,它默认继承了类java.lang.Enu ...

  10. 设置JQuery的Ajax方法同步

    Ajax请求默认的都是异步的如果想同步 async设置为false就可以(默认是true) var html = $.ajax({  url: "some.php",  async ...