`
fantaxy025025
  • 浏览: 1309479 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Java的class编译和运行循环,先有鸡还是先有蛋!

阅读更多

如果有两个方法,互相调用,那么何时了呢?

这个问题早在1、2年前就发现过了,可以用  来解决,但是这种先有鸡还是先有蛋的问题还是又碰见了~

 

/**
 * 下面有问题吗?请仔细看看
 * 如果告诉你是考试类的加载机制的,你能看出问题来吗?
 * 看不出来就看看答案吧~
 */
public class SimpleTest {

    public void f(){
        B b = new B();
    }
   
    public static void main(String[] args) {
        SimpleTest obj = new SimpleTest();
        obj.f();
    }
}
class A{
    static{
        System.out.println("class A loaded!");
    }
    public A(){
        System.out.println("A init!");
    }
    B b = null;
}
class B{
    static{
        System.out.println("class B loaded!");
    }
    public B(){
        System.out.println("B init!");
    }
    A a = null;
}
/*
 * 答案是:没有问题。
 * 运行输出是:
class B loaded!
B init!
 * class A并没有被加载,虽然类B中看见了A,但是类A并没有被用到,既没有用到new
 * 也没有碰到使用类A的静态成员,因此类A没有被加载!
 */

 

/**
 * 再往下看吧~
 * 看不出来就看看答案吧~
 */
public class SimpleTest {

    public void f(){
        B b = new B();
    }
   
    public static void main(String[] args) {
        SimpleTest obj = new SimpleTest();
        obj.f();
    }
}
class A{
    static{
        System.out.println("class A loaded!");
    }
    public A(){
        System.out.println("A init!");
    }
    B b = null;
}
class B extends A {
    static{
        System.out.println("class B loaded!");
    }
    public B(){
        System.out.println("B init!");
    }
    A a = null;
}

/*
 * 答案是:没有问题。
 * 运行输出是:
class A loaded!
class B loaded!
A init!
B init!
 * new B时,先加载父类static成员,之后加载子类static成员,
 * 接着父类A的实例成员b初始化null(此时因为只是看到了B并没有用,因此不加载类B)
 * 最后初始化B
 */

 

/** 继续吧~ */

class A{
    static{
        System.out.println("class A loaded!");
    }
    public A(){
        System.out.println("A init!");
    }
    B b = new B() ;
}
class B extends A {
    static{
        System.out.println("class B loaded!");
    }
    public B(){
        System.out.println("B init!");
    }
    A a = null;
}
/*
 * 答案是:有问题!!
 * 运行输出是:
class A loaded!
class B loaded!
Exception in thread "main" java.lang.StackOverflowError
    at com.june.study.class_compile_resircle.A.<init>(SimpleTest.java:53)
    ...
 * new B时,先加载父类static成员,之后加载子类static成员,
 * 接着父类A的实例成员b初始化new B()(此时因为不只是看到了B还要用,因此必须加载类B)
 * 但是加载类B的前提是类A的成员b必须正确初始化后才行,这就导致了不停的循环:有B需先有A,有A需先有B
 * ,最后java的stack检测到运行期异常了!这里编译确实没有问题的!!
 */

 

这是运行期异常,但编译期没有异常哦!!

 

再看看这个吧~

package study_sun.reflect.Reflection;

public class A {
    B b = null;
    public void link(B b){
        this.b = b;
        b.link(this);
    }
}

package study_sun.reflect.Reflection;

public class B {
    A a = null;
    public void link(A a){
        this.a = a;
        a.link(this);
    }
   
    public static void main(String[] args){
        A a = new A();
        B b = new B();
        a.link(b);
    }
}
/* 结果:Exception in thread "main" java.lang.StackOverflowError */

 

如果换成这样呢!

class A {
    B b = null;
    public void link(B b){
        this.b = b;
//        b.link(this);
        if(Reflection.getCallerClass(2) != B.class)b.link(this);
    }
}
class B {
    A a = null;
    public void link(A a){
        this.a = a;
        //a.link(this);
        if(Reflection.getCallerClass(2) != A.class) a.link(this);
    }
}

// okay~

分享到:
评论

相关推荐

    java class反编译工具

    在描述中提到的工具,是一个小巧而实用的Java Class反编译器,用户只需运行`.exe`可执行文件,然后选择要反编译的`.class`文件,即可在指定目录下生成对应的`.java`文件。 Java字节码是Java源代码经过编译后的中间...

    Java Class文件反编译工具 jd-gui

    Java Class文件是Java程序编译后的二进制格式,它包含了类和接口的定义、方法体、常量池等信息,但这些信息是以机器可读的字节码形式存在,对于人类来说不易理解。为了查看和理解Class文件内部的源代码,我们就需要...

    java class反编译后的代码还原

    Java类反编译后的代码还原是指将编译后的Java类文件(.class)转换回Java源代码的过程。在这个过程中,可能会出现一些不正常的代码,例如label0 :_L1 MISSING_BLOCK_LABEL_30、JVM INSTR ret 7、JVM INSTR ...

    java反编译(将class文件反向编译成java源文件)

    Java反编译是一种技术,它允许开发者从已编译的.class文件中恢复原始的.java源代码。这在一些情况下非常有用,例如分析第三方库的内部实现、研究代码逻辑或者在丢失源代码时恢复源码。Java编译器将源代码转换成字节...

    java超强的反编译工具,可直接反编译class和jar后生成java

    Java的反编译工具通常能够处理.class(单个类文件)和.jar(包含多个类文件的打包文件)格式,生成接近原始Java源代码的文本。 在Java领域,有许多知名的反编译工具,例如JD-GUI、Procyon、FernFlower等,这些工具...

    class文件反编译成java的工具Xjad

    在IT行业中,有时候我们需要对已编译的.class文件进行反编译,以便查看或理解其原始的源代码,这通常是由于失去了源代码或者需要研究已有的二进制代码。在这个场景下,Xjad是一个非常实用的工具,专门用于将.class...

    java 反编译工具

    Java反编译工具是开发者在特定情况下非常有用的工具,它们能够将已编译的Java字节码(.class文件)转换回源代码形式,帮助我们理解或修复已有的Java程序,尤其是在没有源代码的情况下。标题提到的“java 反编译工具...

    JAVA反编译工具 JAD

    JAVA反编译工具JAD是Java开发者和逆向工程爱好者常用的一款工具,它能够将已编译的Java字节码(.class文件)转换回源代码格式,使得开发者可以查看和理解原本被编译隐藏的代码逻辑。在软件开发、调试、学习开源库...

    java完全反编译工具

    了解和掌握Java反编译工具,对于Java开发者来说是一项重要的技能,它能帮助我们更好地理解和利用已存在的Java资源,提升开发效率和问题解决能力。在使用这些工具时,应遵循相关法律法规,并尊重他人的知识产权。

    Java批量编译

    ### Java批量编译技术解析与应用 在软件开发过程中,特别是在大型项目中,代码的管理...无论是通过编写Java代码、使用构建工具还是自定义脚本,掌握批量编译的技术和方法对于每一个Java开发者来说都是不可或缺的技能。

    java反编译工具decomp3.11.11.95

    Java的编译过程将源代码(.java文件)转换为字节码(.class文件),这个字节码是平台无关的,并能在任何支持Java的JVM(Java虚拟机)上运行。然而,字节码并不直接对应于源代码,因此,如果没有源代码,理解和修改...

    java反编译工具-XJad

    Java反编译工具,如XJad,是程序员在研究和学习Java代码或者逆向工程时的重要工具。它们能够将已编译的.class文件转换回源代码格式,这对于理解闭源软件的工作原理、修复错误或者查找病毒代码等活动非常有用。在Java...

    Java反编译工具

    Java反编译工具是开发者和逆向工程人员用于查看Java字节码的工具,它们能够将编译后的`.class`文件转换回可读的源代码形式。这些工具对于理解已有的库函数、学习代码实现或者在没有源码的情况下调试Java程序非常有用...

    小颖Java反编译软件

    Java Class文件是Java虚拟机(JVM)运行的二进制代码形式,它们是通过Java编译器将源代码编译后的产物。这些文件包含了方法、变量、常量池等元数据,但不包含原始的注释和源代码结构。因此,当需要查看类文件的具体...

    java反编译工具

    Java反编译工具是开发人员在理解和学习Java代码或者对已有的Java类库进行逆向工程时常用的工具。这些工具可以将已经编译过的.class文件转换回可读性较高的源代码形式,虽然不能完全恢复原始的.java文件,但能够帮助...

    java反编译.zip

    Java反编译是Java开发中一个重要的辅助工具,主要用于查看和理解Java字节码(.class文件)的内容。由于Java的源代码(.java文件)在编译后会被转化为字节码,这些字节码是机器不可读的,因此,当我们需要查看或分析...

    熟悉Java程序的编辑、编译和运行环境.doc

    #### 一、Java 程序的编辑、编译和运行环境 ##### 实验目的概述 本次实验旨在帮助学习者掌握Java程序的基本开发流程,包括但不限于环境配置、基本语法理解以及简单程序的设计与实现。通过实践操作加深对Java语言的...

Global site tag (gtag.js) - Google Analytics