动手动脑_10.17
一、以下代码为何无法通过编译?哪儿出错了?
答:如果没有构造方法,类会提供一个默认的。类提供了一个自定义的构造方法,导致系统不再提供默认构造方法。
二、如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
答:1、执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
2、执行类的构造函数。
类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。
三、请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
答:1、静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;
2、非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;
3、非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
4、静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
5、非静态初始化块可以针对多个重载构造函数进行代码复用。
四、静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
答: public class Test{
int j =5;
static int value;
public static void A()
{
System.out.println(value);
}
public int B()
{
int x = 100;
return x;
}
public static void main(String args[]) {
Test3 a = new Test3();
value = a.B();
a.A();
}
}
五、两对整数明明完全一样,为何一个输出true,一个输出false?
答:
输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
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() {} }
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() {} }
从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。(查资料)