课后作业——2022.10.02
1.动手动脑1
问题:以下代码为何无法通过编译?哪儿出错了?
原因:
首先,当类没有定义构造函数时,会自动生成一个无参的构造方法,但当类中定义了构造方法时,就会覆盖自动生成的构造方法,
这是只能使用类中定义的构造函数,题中类已经构造一个有参的构造方法,需要参数才能调用,而主函数中只能调用类中的构造
方法,但调用没有参数,导致匹配错误,所以会产生错误。
2.动手动脑2
问题:请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
class Root { static { System.out.println("Root的静态初始化块"); } { System.out.println("Root的普通初始化块"); } public Root() { System.out.println("Root的无参数的构造器"); } } class Mid extends Root { static { System.out.println("Mid的静态初始化块"); } { System.out.println("Mid的普通初始化块"); } public Mid() { System.out.println("Mid的无参数的构造器"); } public Mid(String msg) { //通过this调用同一类中重载的构造器 this(); System.out.println("Mid的带参数构造器,其参数值:" + msg); } } class Leaf extends Mid { static { System.out.println("Leaf的静态初始化块"); } { System.out.println("Leaf的普通初始化块"); } public Leaf() { //通过super调用父类中有一个字符串参数的构造器 super("Java初始化顺序演示"); System.out.println("执行Leaf的构造器"); } } public class TestStaticInitializeBlock { public static void main(String[] args) { new Leaf(); } }
输出结果:
总结:
1)静态初始化块只执行一次
2)执行子类的对象时,会先执行父类的静态初始化块的
3.动手动脑3
问题:神奇代码(StrangeIntegerBehavior.java)输出诡异的结果,原因何在?
public class StrangeIntegerBehavior { public static void main(String[] args) { Integer i1=100; Integer j1=100; System.out.println(i1==j1); Integer i2=129;//false Integer j2=129; System.out.println(i2==j2); } }
输出结果:
原因:
因为它们调用的Interger类的方法不同,所以结果不同
下面这段代码是Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
而其中IntegerCache类的实现为:
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
从代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,
便返回指向IntegerCache.cache中已经存在的对象;否则创建一个新的Integer对象。
100会直接从cache中取已经存在的对象,所以指向的是同一个对象,而后者则是分别指向不同的对象。