无限递归的构造器和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 ...
随机推荐
- Headroom.js
下载 Development (3.7kB) Production (1.7kB) Headroom.js 是什么? Headroom.js 是一个轻量级.高性能的JS小工具(不依赖任何工具库!),它 ...
- UESTC_握手 CDOJ 913
握手 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status ...
- 剑指offer-面试题6.重建二叉树
题目:输入某二叉树的前序遍历和中序遍历结果,请重建出该二叉树.假设 输入的前序遍历和中序遍历的结果都不含重复的数字.例如输入前序遍历 序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2, ...
- java_IO流之 NIO
NIO 定义 即新IO,在JDK1.4的java.nio.*包中引入,其目的在于提高速度. 在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生 ...
- LINUX下 Udev详解
如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...
- 性能优化之Hibernate缓存讲解、应用和调优
JavaMelody——一款性能监控.调优工具, 通过它让我觉得项目优化是看得见摸得着的,优化有了针对性.而无论是对于分布式,还是非分布,缓存是提示性能的有效工具. 数据层是EJB3.0实现的,而EJ ...
- CF 338 D GCD Table(CRT)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 给定一个序列,a[1 ..k],问是否存在(i , ...
- Android Project from Existing Code 生成 R 文件错误、失败等问题解决办法 - 持续更新
Android Project from Existing Code 生成 R 文件错误.失败等问题解决办法 - 持续更新 git 上的项目,pull下来之后用Android Project fro ...
- IOS将UIView转化为UIImage
+(UIImage*)createImageFromView:(UIView*)view { //obtain scale CGFloat scale = [UIScreen mainScreen]. ...
- sharepreference实现记住password功能
SharePreference是用于保存数据用的.主要调用Context.getSharePreferences(String name, int mode)方法来得到SharePrefere ...