无限递归的构造器和javap使用指南
无限递归的构造器和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使用指南的更多相关文章
- 无限“递归”的python程序
如果一个函数直接或者间接调用了自己,那么就形成了递归(recursion),比如斐波那契数列的一个实现 def fib(n): if n <= 2: return 1 else: return ...
- 【整理】iview Tree数据格式问题,无限递归树处理数据
iview Tree数据格式问题,无限递归树处理数据 https://juejin.im/post/5b51a8a4e51d455d6825be20
- -java转json hibernate懒加载造成的无限递归问题
1.在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系. JoinColumn(name="pid") 2. 在保存数据时,总是先保存的 ...
- jackson java转json hibernate懒加载造成的无限递归问题
@JsonIgnore @JsonFilter @JsonBackReference @JsonManagedReference @JsonIgnoreProperties jackson中的@Jso ...
- hibernate无限递归问题
项目异常如下: 2018-01-26 17:12:38.162 WARN 3128 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionReso ...
- JPA一对多循环引用的解决&&JackSon无限递归问题
说是解决,其实不是很完美的解决的,写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的,能否知道一二. 下面说说出现问题: 问题是这样的,当我查询一个一对多的实体的时候,工具直接就爆了,差不多我就 ...
- C# .NetCore简单实现无限递归的功能
1:在实际开发中,我们会经常使用到无限递归的情况,如菜单,父子级等的情况 2:Code 1 using System; 2 using System.Collections.Generic; 3 us ...
- vue 无限递归级联组件实现方案
最终组件效果图: 无限级联组件实现思想: 在这里有一个很重要的地方就是前端组件如何与后端匹配方法协调好,无限级联很好实现,但是如何让服务器端可以成功的匹配到条件是一个问题,在这里我借鉴了html元素的 ...
- SqlServer与Linq 无限递归目录树且输出层级
ALTER VIEW [dbo].[view_TreeLevel] AS WITH cte AS ( SELECT a.ModuleID , a.Module_Name , a.Module_Desc ...
随机推荐
- 性能优化之Hibernate缓存讲解、应用和调优
JavaMelody——一款性能监控.调优工具, 通过它让我觉得项目优化是看得见摸得着的,优化有了针对性.而无论是对于分布式,还是非分布,缓存是提示性能的有效工具. 数据层是EJB3.0实现的,而EJ ...
- 【枚举+数学】【HDU1271】整数对 难度:五颗星
整数对 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- Java - 文件(IO流)
Java - 文件 (IO) 流的分类: > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter ...
- PropertyGrid—添加属性Tab
零.引言 PropertyGrid用来显示和编辑对象的属性,前面已经简单介绍了如何使用该控件和提供不同的属性编辑方法.前面主要讲如何使用该控件,但有时,该控件无法满足我们的需求,就需要对其进行扩展.本 ...
- SQL Server服务启动失败,错误代码:10048
今天打开电脑后遇到了一个奇葩的问题,启动Sql Server服务时,出现如下图所示错误:
- 定时排程刷新微信access-token
微信公众号开发中最常遇到的就是调用接口时候需要有API的access-token(非网页授权的access-token),有了这个token之后,才可以发生模板消息等.这里的做法主要是用nodejs的 ...
- 关于javascript 数组的正态分布排序的一道面试题
最近几天顶着上海40°的凉爽天气找工作,心里是开心的不要不要的,每次面试都是要坐那里出半天汗才能回过神来,感觉到了这个世界对我深深的爱意,言归正传,面试过程中碰到了几次笔试,其中有这么一道题,由于实际 ...
- thinkPHP入门 一
简介 ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,尤其注重开 ...
- eclipse中的debug的用法
最基本的操作是: 1.首先在一个java文件中设断点,然后debug as-->open debug Dialog,然后在对话框中选类后--> Run 当程序走到断点处就会转到debug视 ...
- Android 上传库到Binary的操作
第一次,按照网上教程配置需要的配置文件,上传成功 1.0版本. 以后更新的时候 输入 : install ,执行task 然后再输入:bintrayUpload ,执行task,看下面控制台输出信息, ...