Java初始化顺序

实例变量的实例化

 

三个地方:

  1. 定义实例变量指定初始值
  2. 非静态初始化块中对实例变量指定初始值
  3. 构造器中对实例变量指定初始值

 

其中,1、2中方式比第三种方式更早执行,1、2种执行顺序与它们在源程序中的排列顺序相同。

 

 

类变量的初始化

 

两个地方:

  1. 定义是指定
  2. 静态初始化块中指定

 

这两种方式的执行顺序与它们在源程序中的排列顺序相同

 

public class StaticInitTest {

    static int count = 2;
    
    static {
        System.out.println("StaticInitTest静态初始化块");
        name = "Java编程";
    }
    
    static String name = "疯狂java讲义";
    
    public static void main(String[] args) {
        
        System.out.println("count类变量的值:" + StaticInitTest.count);
        System.out.println("name类变量的值:" + StaticInitTest.name);
    }
}

输出:

StaticInitTest静态初始化块

count类变量的值:2

name类变量的值:疯狂java讲义

解析:name刚开始赋值为Java编程

 

 

 

 

从内存看Java实例化

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 p = new Price(2.8);
        
        System.out.println(p.currentPrice);
    }
}

输出:-2.8

17.2

 

解析:

初始化分为以下两个阶段:

1.  系统为Price的两个类变量分配内存空间

2.  按初始化代码的排列顺序执行初始化

 

Java初始化的内存分配

(注意java在继承变量和方法的时候是有区别的)

当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。但通过该变量调用它引用的对象的实例方法时,该方法的行为将由它实际所引用的对象来决定。

 

原因:Java编译器会将父类的方法加到子类中去,而父类中的实例变量则不会。

 

结论:当一个程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为其父类中定义的所有实例变量分配内存。

 

public class Test {

    public static void main(String[] args) {
        
        new Derived();
    }
}

class Base{
    
    private int i = 2;

    public Base(){

        //要弄清楚这里的this指向的是子类
        //可以通过this.getClass开看
        //所以this.display()调用的是子类的,输出的i当然就是子类的i了
        this.display();
    }
    
    public void display(){
        System.out.println(i);
    }
}

class Derived extends Base{
    
    private int i = 22;
    
    public Derived(){
        i = 222;
    }
    
    public void display(){
        System.out.println(i);
    }
}

输出:0

 

例子2:
class Animal{
    
    private String desc;
    public Animal(){
        this.desc = getDesc();
    }
    
    public String getDesc(){
    
        System.out.println("Animal");
        return "Animal";
    }
}
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(){
        
        System.out.println("Wolf[name=" + name + " ,weight=" + weight +"]");
        return "Wolf[name=" + name + " ,weight=" + weight +"]";
    }
    
    public static void main(String[] args) {
        
        System.out.println(new Wolf("灰太狼", 32.3));
    }
}

 

 

输出:Wolf[name=null ,weight=0.0]

javaSyntax.Wolf@770848b9

 

解析:因为子类重写了父类的方法,所以实例化子类实例时,不会把父类的那个方法复制过来,所以getDesc()调用的是子类的重写方法

 

 

例子3:

 

class Fruit{
    
    String color = "未确定颜色";
    
    public Fruit getThis(){
        
        return this;
    }
    
    public void info(){
        
        System.out.println("Fruit 方法");
    }
}



public class Apple extends Fruit{

    @Override
    public void info(){
        
        System.out.println("Apple 方法");
    }
    
    //通过super调用父类的info()方法
    public void AccessSuperInfo(){
        
        super.info();
    }
    
    //尝试返回super关键子代表的内容
    public Fruit getSuper(){
        
        return super.getThis();
    }
    
    String color = "红色 ";
    
    public static void main(String[] args) {
        
        Apple a = new Apple();
        Fruit f = a.getSuper();
        
        System.out.println("a和f所引用的对象是否相同:" + (a == f));
        System.out.println("访问a所引用对象的color实例变量: " + a.color);
        System.out.println("访问f所引用对象的color实例变量:" + f.color);
        
        a.info();
        f.info();
        
        //调用AccessSuperInfo来调用父类的info()方法
        a.AccessSuperInfo();
        
    }
}

 

posted @ 2014-03-18 15:37  mynona  阅读(453)  评论(0编辑  收藏  举报