首页 > 试题广场 >

下面程序的运行结果是() public class Clas

[单选题]
下面程序的运行结果是()
public class ClassA {
    static int count = 0;
    static {
        count++;
        System.out.println("A");
    }
    public ClassA() {
        System.out.println("B");
    }
}
public class ClassB {
    static {
        ClassA t2;
        System.out.println("C");
    }
    public static void main(String[] args) {
        Class c1;
        Class c2;
        Class c3;
        try {
            c1 = ClassA.class;
            c2 = Class.forName("ClassA");
            ClassA a = new ClassA();  
            c3 = a.getClass();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        if (c2 == c1&& c1 == c3) {
            System.out.println("D");
        } else {
            System.out.println("E");
        }
        System.out.println(ClassA.count);
    }
}

  • C  A   B  D  1
  • C  A  B  D  2
  • A  C  B  D  2
  • C  A  B  E  1
  • A  C  B  E  3
看了其他人的解析,发现他们似乎都没有认真执行过这段代码,
特别是  :  ClassA a = new ClassA(); 初始化ClassA,输出“AB”  这个是错的。
因为 在  c2 = Class.forName("ClassA"); 这时候 ClassA类被初始化了。 这时候会执行静态代码块,输出 A,只是没有执行 构造方法。
这时候 ClassA a = new ClassA(); 仅仅只是执行了 构造代码块 输出了 B
因为  类的静态代码块 只会 执行一次。 
jvm会执行静态代码段,你要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。
这里同时考察了 Class.forName("ClassA") 加载和 new ClassA() 的区别

发表于 2019-07-23 10:12:53 回复(10)
触发类的初始化的四种情况: 1.通过new关键字实例化对象,读取或设置类的静态变量,调用类的静态方法, 2.通过反射方式执行以上三种行为 3.初始化子类的时候,会触发父类的初始化 4.作为程序的入口直接运行时(就是类中直接调用main函数) 那么题中b类是程序的入口(main);分割线 (づ ●─● )づ首先对b进行类加载,也就是会调用静态变量或静态方法块,第一个输出C; 分割线(づ ●─● )づ继续,补充一点:类加载只会执行一遍;那么c1==c2==c3,三个Class对象指向的都是同一份内存空间; 分割线(づ ●─● )づ再补充一点:类的生命周期:加载,连接,初始化,使用,卸载;分割线(づ ●─● )づ new A()执行时,会对A进行类加载,并且到达使用阶段,也就是会调用构造器,那么输出就是AB; 分割线(づ ●─● )づ上面提到c1==c2==c3,那么输出C; 分割线(づ ●─● )づ上面也提到类的加载只会执行一遍,所以count为1。 纯手机码,欢迎补充指正(づ ●─● )づ
编辑于 2019-07-22 09:51:34 回复(0)
这道题主要考的类的加载机制:
1.被标明为启动类的类(即包含main()方法的类)要初始化,所以ClassB最先初始化
2.ClassB没有父类,所以初始化自身的静态变量和静态块赋值(按照声明顺序),输出“C”
3.c2 = Class.forName("ClassA"); 此时不是通过构造器获得c2对象,因此只会执行ClassA的static代码块,输出A,不会执行构造器代码;
4.ClassA a =newClassA(); 此时构造器代码执行,输出B,但是由于static代码块只执行一次,所以这一步不执行;
5.因为类的加载信息只会在永久代里留存一份,所以c1,c2,c3实际上共用同一个ClassA.class对象,所以输出“D”
6.静态块static{}只会执行一次,所以count=1。
最后要注意的是,21-24行都是创建类的对象的方法,并且都是创建的ClassA的对象,当21行创建以后,其实ClassA的对象就被保存下来了额,后面的几种方式没有创建新的ClassA对象,而是共用之前创建的。
编辑于 2019-09-12 15:37:05 回复(0)
这是我理解的,不知道对不对,贴出来和大家一起分享
/**
 * jvm类加载顺序 加载 -> 链接(验证 -> 准备 -> 解析) -> 初始化 -> 使用 -> 卸载 
 */
public class ClassB {//classB执行加载、链接、初始化
    static {//ClassB被初始化,执行静态代码块
        ClassA t2; //ClassA执行加载、链接,并在内存中创建类一个模板
        System.out.println("C");
    }
    public static void main(String[] args) {
        Class c1;
        Class c2;
        Class c3;
        try {
            c1 = ClassA.class;//ClassA执行加载、链接,c1为获取ClassA在内存中创建的模板
            c2 = Class.forName("ClassA");//ClassA执行初始化,第一次初始化,执行ClassA静态代码块,c2通过反射获取ClassA的模板来创建
            ClassA a = new ClassA();//ClassA执行初始化,第二次初始化,不执行静态代码块,我理解未new表示开始使用,执行构造函数,复制内存中ClassA的模板
            c3 = a.getClass();//获取a的模版
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        if (c2 == c1 && c1 == c3) {//所以c1、c2、c3都是同一个模板,所以内存地址相同
            System.out.println("D");
        } else {
            System.out.println("E");
        }
        System.out.println(ClassA.count);
    }
}


发表于 2019-09-07 10:54:33 回复(0)
A的输出应该在c2 = Class.forName("ClassA");处,如果ClassA的调用不正确,程序会报出ClassNotFoundException异常
编辑于 2019-07-10 08:50:52 回复(1)
这道题主要考的类的加载机制:
1.被标明为启动类的类(即包含main()方法的类)要初始化,所以ClassB最先初始化
2.ClassB没有父类,所以初始化自身的静态变量和静态块赋值(按照声明顺序),输出“C”
3.ClassA a = new ClassA(); 初始化ClassA,输出“AB”
4.因为类的加载信息只会在永久代里留存一份,所以c1,c2,c3实际上共用同一个ClassA.class对象,所以输出“D”
5.静态块static{}只会执行一次,所以count=1

编辑于 2019-10-21 17:08:22 回复(11)
我输出的答案是CABE1啊
发表于 2019-10-24 15:34:54 回复(0)
class ClassA{
    static int count = 0;
    static {
        count++;
        System.out.println("A");
    }
    public ClassA(){
        System.out.println("B");
    }
}
public class ClassB {
    static {
        ClassA t2;
        System.out.println("C");
    }

    public static void main(String[] args) {
        Class c1;
        Class c2;
        Class c3;
        try {
            c1 = ClassA.class;
            c2 = Class.forName("ClassA");
            ClassA a = new ClassA();
            c3 = a.getClass();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        if(c2==c1 && c1==c3){
            System.out.println("D");
        }else {
            System.out.println("E");
        }
        System.out.println(ClassA.count);
    }
}


为什么我的代码会在Class.forName那里报错呀
发表于 2019-10-23 10:00:10 回复(2)
1、执行main方***输出C
2、Class.forName("ClassA")会输出A
3、new ClassA()会输出B
4、类实际只加载了一次,static代码块也只执行了一次,因此输出D;1
发表于 2019-09-16 19:22:13 回复(0)
果然是顺丰
发表于 2019-08-23 21:48:56 回复(0)

程序

class ClassA {
    static int count = 0;
    static {
        System.out.println("static A");
        count++;
        System.out.println("A");
    }
    public ClassA() {
        System.out.println("ClassA()");
        System.out.println("B");
    }
}

public class CharCodeTest{
    static {
        System.out.println("static B");
        ClassA t2;// 没有调用构造器,ClassA的class对象就没有加载
        System.out.println("C");
    }
    public static void main(String[] args) {
        System.out.println("static B main");
        // char foo = '重';
        // System.out.print(foo);

        // 类的加载和初始化
        Class c1;
        Class c2;
        Class c3;
        try {
            c1 = ClassA.class;
            c2 = Class.forName("ClassA");
            ClassA a = new ClassA();  
            c3 = a.getClass();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        if (c2 == c1&& c1 == c3) {
            System.out.println("D");
        } else {
            System.out.println("E");
        }
        System.out.println(ClassA.count);
    }
}

输出

static B
C
static B main
static A
A
ClassA()
B
D
1
发表于 2019-07-09 12:52:56 回复(2)

出题不严谨

发表于 2019-05-26 10:11:15 回复(1)
发表于 2019-03-31 21:57:56 回复(2)