本文是根据JAVA解惑这本书,做的笔记。电子书见:http://download.csdn.net/detail/u010378705/7527721
谜题46
函数重载的问题。
JAVA重载解析过程:1. 选取所有可用的方法或者构造器;2. 从过程1中选取的方法或构造器中选择最精确的。
一般而言:可以强制要求编译器选择一个精确的重载版本,将实参转型为形参所声明的类型。
如果需要让每一个子类都具有某个域的单独拷贝,必须在每一个子类中声明一个单独的静态域。
如果每一个实例都需要一个单独的拷贝,则可以在基类中声明一个非静态域。
对静态方法的调用不存在任何动态分配机制。静态方法是编译时刻选定的,根据修饰符编译期类型选定的。
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private final int beltSize;
private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);
private Elvis() {
beltSize = YEAR - 1930;
}
public int beltSize() {
return beltSize;
}
public static void main(String[] args) {
System.out.println(INSTANCE.beltSize());
}
}
初始化的问题。
final类型的静态域被初始化之前存在被读取的可能,此时该静态域只是所属类型的缺省值。
final类型的域只有在初始化表达式是常量表达式时,才是常量。
类的初始化循环有待进一步理解。
谜题50
instanceof的问题
当instanceof左操作数为null时,返回false。
当instanceof左右操作数都是类的时候,其中一个必须是另一个的子类型,否则编译错误。
转型操作符的行为与instanceof相同,当转型操作的两种类型都是类时,必须其中一个是另一个子类型。
谜题51
class Point {
protected final int x, y;
private final String name;
Point(int x, int y) {
this.x = x;
this.y = y;
name = makeName(); // 3. 调用子类的方法。
}
protected String makeName() {
return "[" + x + "," + y + "]";
}
public final String toString() {
return name;
}
}
public class ColorPoint extends Point{
private final String color;
ColorPoint(int x, int y, String color) {
super(x, y); //2. 转向父类的构造函数。
this.color = color; // 5. 初始化该属性。
}
protected String makeName() {
//4.在子类的构造函数结束前执行。
return super.makeName() + ":" + color;
}
public static void main(String[] args) {
//1. 调用子类的构造函数。
System.out.println(new ColorPoint(1, 2 , "red"));
}
}
构造函数调用了子类覆写的方法。
实例初始化循环,可以采用惰性初始化。
谜题52
class Cache {
static {
initializedIfNecessary();
}
private static int sum;
public static int getSum() {
initializedIfNecessary();
return sum;
}
private static boolean initialized = false;
private static synchronized void initializedIfNecessary() {
if (! initialized) {
for (int i = 0; i < 100; i++) {
sum += i;
}
initialized = true;
}
}
}
public class Client {
public static void main(String[] args) {
System.out.println(Cache.getSum());
}
}
同时使用了惰性初始化和积极初始化。
初始化顺序对结果的影响。
修改后的程序
class Cache {
private static final int sum = computeSum();
private static int computeSum() {
int result = 0;
for (int i = 0; i < 100; i++) {
result += i;
}
return result;
}
public static int getSum() {
return sum;
}
}
谜题53
讲述了私有构造器捕获惯用法。
<span style="font-size:18px;">class Thing {
public Thing(int i) {
System.out.println("Thing:" + i);
}
}
public class MyThing extends Thing {
@SuppressWarnings("unused")
private final int arg;
public MyThing() {
this(1);//可以调用其他类的方法获取返回值。
}
private MyThing(int i) {
super(i);
arg = i;
}
}</span>
谜题54
静态方法调用时,实例不起作用。静态方法是属于类的。
谜题55
java语言规范不允许一个本地变量声明语句作为一条语句在循环中重复执行。一个本地变量声明作为一条语句,只能直接出现在一个语句块中(花括号中的)。
for (int i = 0; i < 10; i++)
String str = "123";
这个编译不通过,修改正确为:
for (int i = 0; i < 10; i++) {
Stirng str = "123";
}
Java解惑五:类之谜,布布扣,bubuko.com
Java解惑五:类之谜