无限递归的构造器和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 ...
随机推荐
- UESTC_酱神寻宝 2015 UESTC Training for Dynamic Programming<Problem O>
O - 酱神寻宝 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- Canvas之动态波浪效果_陈在真Sunny_chen_新浪博客
Canvas之动态波浪效果_陈在真Sunny_chen_新浪博客 Canvas之动态波浪效果 (2012-04-26 09:04:51) 转载▼
- Java 获取Linux 的IP地址
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...
- 自定义View的封装
通过上一个博文的自定义View的编写后,发现代码其实挺复杂的,所有这里通过对代码进一步的优化,即用到了java的一个重要的特点:封装.通过对父类的方法进行封装,然后在子类继承后实现相应的函数即可,达到 ...
- MyEclipse通过JDBC连接MySQL数据库基本介绍
转载自:http://www.jb51.net/article/31876.htm 1.前提是MyEclipse已经能正常开发Java工程 2.安装MySQL 个人使用的是版本是 mysql-5.0. ...
- 我的Android进阶之旅------>Android服务的生命周期回调方法
先引用一段官网上的文字 ======================================================================================== ...
- Servlet页面间对象传递的方法
Servlet页面间对象传递的方法 1.request 2.session 3.application 4.cookie 5.其它的
- 关于 jsp:include 传参的用法
引用模版页面的代码,如下: <jsp:include page="/WEB-INF/template/nav_template.jsp"> <jsp:pa ...
- 【转】通过Navicat for MySQL远程连接的时候报错mysql 1130的解决方法
错误代码是1130,ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是无法给远程连接的用 ...
- c语言字符串比较函数strcmp
strcmp(s1,s2) 说明: 当s1<s2时,返回值<0 当s1=s2时,返回值=0 当s1>s2时,返回值>0两个字符串自左向右逐个字符相比(按ASCII值大小相比较) ...