1.类变量初始化:
class Price{
final static Price INSTANCE = new Price(2.8);
static double initPrice = 20;
double currentPrice ;
public Price (double discount) {
currentPrice = initPrice - discount;
}
}
public class PriceTest{
public static void main(String[] args){
System.out.println(Price.INSTANCE.currentPrice);
Price price = new Price(2.8);
System.out.println(price.currentPrice);
}
}
(1)系统先为INSTANCE ,initPrice两个类变量分配内存空间,此时INSTANCE和initPrice分别为null和0;
(2)系统为INSTANCE,initPrice两个变量赋值,对INSTANCE赋值时调用Price(2.8),创建Price实例,此时initPrice还为0,所以INSTANTCE的currentPrice为-2.8。接着系统为initPrice赋值为20,但是对INSTANCE中的currentPrice没影响了,所以打印的结果为-2.8;
注意:如果将1、2处的代码交换位置,则不会出现这个问题了。
2.父类调用子类对象的实例变量
/**
* 1.在this在构造器中,this代表正在初始化的java对象,[此时this位于Base()构造器内,
* 但这些代码实际放在Derived()构造器内执行--是Derive()构造器 隐式调用了Base()构
* 造器代码],即new的这个Derived对象,因此(2)处输出"Derived";
* 2.因为this虽然代表Derived对象,但它位于Base构造器中,它的编译时类型是Base,而
* 它实际上引用了一个Derived对象。编译时类型和运行时类型不同时,通过该变量访问
* 它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。但通过该变量
* 调用它引用的对象实例方法时,该方法行为将由它实际所引用对象来决定。
*
*/
class Base{
private int i = 2;
public Base(){
System.out.println(this.i);//(1)
display();
System.out.println(this.getClass().getName());//(2)
}
public void display(){
System.out.println("super:"+i);//(3)
}
}
class Derived extends Base{
private int i =22;
public Derived(){
i = 222;
}
public void display(){
System.out.println("self:"+i);//(4)
}
}
public class Test{
public static void main(String[] args){
new Derived();//(5)
}
}
注意:构造器只负责将java对象实例变量执行初始化(即赋初值),在执行构造器代码之前,改对象的内存已经分配好了,这些内存里值要么是null要么是0或者false。
3.
/**
* 如果父类构造器调用了被子类重写的方法,且通过子类构造器来创建子类对象
* 调用(不管显示、隐式)了这个父类构造器,就会导致子类的重写方法在子类构
* 造器的所有代码之前被执行,从而导致子类的重写方法访问不到子类的实例变量
* 值的情形。
*/
class Animal{
private String desc;
public Animal(){
this.desc = getDesc( );
}
public String getDesc(){
return "Animal";
}
public String toString(){
return desc;
}
}
public class Wolf extends Animal{
private String name;
private double weight;
public Wolf(String name,double weight){
this.name = name;
this.weight = weight;
}
@Override
public String getDesc(){
return "Wolf[name="+name+",weight="+weight+"]";
}
public static void main(String[] args){
System.out.println(new Wolf("红太狼",120));//Wolf[name=null,weight=0.0]
}
}