Java数据初始化

Java数据初始化

一、构造器初始化

1、概念

1.1、构造函数用于对象初始化,默认给定一个无参构造器,若给定了有参构造器,无参构造器需要手动创建
1.2、在Java 中构造器的“初始化”和“创建”捆绑在一起,两者不可分离。
1.3、因为java定义构造器与类名相同,要实现一个类中有多种类型的构造器,所以Java采用了方法重载的形式来实现构造器的多元化。

二、成员初始化

1、概念:如果类中的成员变量没有给定初始值,编译器会给一个默认值,

基本数据类型默认值情况如下
boolean --> false
char --> []
byte --> 0
short --> 0
int --> 0
long --> 0
float --> 0.0
double --> 0.0
对象初始化:如果不创建对象,使用时会出现异常
reference(对象引用) --> null

三、数组初始化

1、数组也是一个对象的形式,和对象一样会分为引用的分配空间,所以在作为成员变量时,如果没有初始化,会被作为引用默认为null
2、数组中的元素,如果只给出了数组大小,而没有给每个元素初始化,则里面的元素会根据类型不同系统分配默认值,类似于上面的基本数据类型默认值(对于数字和字符就是0,对于布尔类型时false);如果时对象数组,则数组里面的引用没有初始化的话时默认的null

四、初始化顺序

静态数据/普通成员数据的初始化

1、概念:在类的内部,定义变量的先后顺序决定了初始化的先后顺序,即使变量定义分布于方法定义之间,他们仍然会在任何方法(包括构造器)被调用之前得到初始化。
2、案例

public class TestUtil {
    public static void main(String[] args) {
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

class Bowl{
    Bowl(int marker){
        System.out.println("Bowl(" + marker + ")");
    }
    void f1(int marker){
        System.out.println("f1(" + marker + ")");
    }
}

class Table{
    static int b = 1;
    static Bowl bowl1 = new Bowl(b);
    Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker){
        System.out.println("f2(" + marker + ")");
    }
    static {
        b = 5;
    }
    static Bowl bowl2 = new Bowl(2);
}

class Cupboard{
    int anInt = 3;
    Bowl bowl3 = new Bowl(anInt);
    {
        anInt = 6;
    }
    static Bowl bowl4 = new Bowl(4);
    Cupboard(){
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker){
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
//输出结果
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

节点:普通成员变量、普通成员对象、普通示例代码块、静态成员变量、静态成员对象、静态代码块、构造方法、普通方法,静态方法
初始化的顺序:(按照定义的顺序)
第一步、静态变量、静态对象、静态代码块(如果他们尚未因前面的对象创建过程而被初始化),静态的数据按照定义的顺序进行加载初始化
第二步、普通成员变量、普通成员对象、普通示例代码块,非静态的数据按照定义的顺序进行加载初始化
第三步、构造方法(实际上是静态方法)
第四步、普通方法和静态方法,只有调用的时候才会被加载
案例解析
1、静态成员只会在首次生产类对象或者首次访问属于哪个类的静态数据成员时(即便从未生成过这个类对象)的时候被初始化一次
2、所有成员变量无论是否时静态,他们都会在任何方法(包括构造器)被调用之前得到初始化

五、继承与初始化

案例

public class Beetle extends Insect{
    private int k = printInit("Beetle.k initialized");
    public Beetle(){
        System.out.println("k=" +k);
        System.out.println("j=" +j);
    }
    private static int x2 = printInit("static Beetle.x2 initialized");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

class Insect{
    private int i = 9;
    protected int j;
    Insect(){
        System.out.println("i=" + i + ",j=" + j);
    }
    private static int x1 = printInit("static Insect.x1 initialized");
    static  int printInit(String s){
        System.out.println(s);
        return 47;
    }
}

案例解析
在Beetle类上启动运行时,所发生的第一件事就是试图访问Beetle.main(),于是加载器开始并找出Beetle类的编译代码(在名为Beetle.class的文件之中),在对他进行加载的过程中,编译器注意到他有一个基类(这是由extends关键字得知的),于是他继续加载,不管你是否要产生一个该基类的对象,编译器都会先去初始化基类,如果这个基类往上还有基类,则继续往上加载,加载顺序是从上而下的;
接下来是加载的顺序
第一步:根基类中的静态数据进行初始化
第二步:往下走进行导出类中的静态数据的初始化
第三步:创建对象,调用构造器,调用构造器的时候由于导出类必须在第一行调用父类的构造器,所以还是继续网上找,找到根基类,然后从跟基类往下执行
第四步:从根基类往下执行的时候,首先需要初始化类中的属性,初始化基本类型为默认值,初始化对象为null;
第五步:属性初始化完以后,开始调用基类的构造器,基类构造器初始化完以后向下执行,开始初始化导出类中的属性,调用导出类中的构造器,以此类推,知道执行完最后一级导出类,整个执行初始化过程完成

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值