冲刺秋招之牛客刷Java记录第二天

发布时间 2023-09-29 16:41:13作者: yx1024

第一题 下列代码输入什么?

public class Test {
    public static Test t1 = new Test();

    {
        System.out.println("blockA");
    }

    static {
        System.out.println("blockB");
    }

    public static void main(String[] args) {
        Test t2 = new Test();
    }
}

解析:
本题考察类加载。
根据跟踪源代码可知,执行main方法之前,Test类就已经加载完毕,也就是说,执行到Test t2 = new Test();的时候,控制台已经打印了blockAblockB

blockAblockB

可以在第4,7,11,15行都打上断点,可以看到程序一开始是从第4行开始执行的。这就说明Test类的加载先于main方法。

创建t2时,再去Test类中执行一次非静态代码块和构造方法,因为没有自定义构造方法,所以只输出非静态代码块的内容。

如果有自定义构造方法,那么先执行非静态代码块,然后执行构造方法。为什么?因为构造方法可能会用到代码块里的东西。把构造方法比喻成吃饭,那么非静态代码块就是把饭菜端到桌子上。

而静态域和静态代码块的优先级就更高了,他俩相当于把饭做好。他俩之间的优先级是:谁先被定义,谁就先被执行。在这道题目中,t1的优先级就比静态代码块高。大家可以把他俩的位置换一下,输出的内容一定是
blockB
blockA
blockA

静态域和静态代码块只会执行一次(类加载时)。
非静态域和非静态代码块每次创建对象时都会被执行。

答案:
blockA
blockB
blockA

第二题 下列代码输出什么?

public class Test2 {
    public static void main(String[] args) {
        test();
    }

    public static void add(Byte b) {
        b = b++;
    }

    public static void test() {
        Byte a = 127;
        Byte b = 127;
        add(++a);
        System.out.print(a + " ");
        add(b);
        System.out.print(b + "");
    }
}

解析:
add(++a):先把a转成byte,然后用a的补码+1,因为byte类型范围是:[-128,127],所以加1后,a=-128。再将a转为Byte类型,此时才开始调用add(-128),执行过程是这样的:

引用传递

由图可知,执行b++之后,红线断开。所以,add方法不会对main中的变量产生影响。所以a=-128,b=127。

答案:
-128 127