Java学习笔记二:初始化(二)

这里主要学习初始化,分为:

1.变量初始化

2.构造函数初始化

3.数组初始化

4.继承初始化

 

1.变量初始化

成员初始化分为两种:

(1)成员变量初始化

在定义成员变量时,如果没有给变量赋于初始值,系统会给出一个默认值。

这里有两种选择:要么使用系统的默认初始值,要么自己定义初始值。

系统给出的默认输出值为:

boolean    false
char       [ ]
byte       0
short      0
int        0
long       0
float      0.0
double     0.0
refenece   null

char初始值为0,显示为空白;String 引用类型默认初始时为null

(2)局部变量初始化

局部变量在使用“基本类型“时必须富商初始值,否则编译器会报错。

 

2.构造函数初始化

(1)成员变量在任何构造函数调用之前被初始化,如:

class Init2
{
    private int i;

    public Init2(int i)
    {
        this.i = i;
    }

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

    private String reference;
}

1).i 在构造函数调用之前已经被赋予初始值0,然后才在构造函数中赋于新值3。

2).不管成员变量散落什么地方,都能够首先初始化。

3).变量的定义顺序决定了初始化的顺序。

 

(2)静态数据库的初始化

这里使用“Java编程思想”的例子

class Bowl
{
    public Bowl(int maker)
    {
        // maker用于标记
        System.out.println("Bowl(" + maker +")");
    }

    public void f1(int maker)
    {
        System.out.println("f1(" + maker +")");
    }
}

class Table
{
    static Bowl bowl1 = new Bowl(1); // 静态成员变量

    public Table()
    {
        System.out.println("Table");
        bowl1.f1(1);
    }

    public void f2(int maker)
    {
        System.out.println("f2(" + maker +")");
    }

    static Bowl bowl2 = new Bowl(2); // 静态成员变量
}

class Cupboard
{
    Bowl bowl3 = new Bowl(3); // 非静态成员变量
    static Bowl bowl4 = new Bowl(4); // 静态成员变量

    public Cupboard()
    {
        System.out.println("Table");
        bowl3.f1(2);
    }

    public void f3(int maker)
    {
        System.out.println("f3(" + maker +")");
    }

    static Bowl bowl5 = new Bowl(5); // 静态成员变量
}

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

    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

执行结果:

Bowl(1)
Bowl(2)
Table
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)
Init3.main()
Bowl(3)
Cupboard
f1(2)
Init3.main()
Bowl(3)
Cupboard
f1(2)
f2(1)
f3(1)

说明:

第一步:首先初始化 static Table table = new Table(); (因为 在调用 Init3 main有静态变量)

1.1.在Table中初始化 static Bowl bowl1 = new Bowl(1);,此时,输出的结果为:Bowl(1)

1.2.在Table中初始化 static Bowl bowl2 = new Bowl(2);,此时,输出的结果为:Bowl(2)

1.3.初始化Table的构造函数,输出: Table,并执行 bowl1.f1(1) 方法,输出:f1(1)

所以在执行完成 static Table table = new Table(); 后,输出结果为:

Bowl(1)
Bowl(2)
Table
f1(1)

第二步:初始化 static Cupboard cupboard = new Cupboard();

2.1.在Cupboard中初始化 static Bowl bowl4 = new Bowl(4);,此时,输出结果为:Bowl(4)

2.2.在Cupboard中初始化 static Bowl bowl5 = new Bowl(5);,此时,输出结果为:Bowl(5)

2.3.在Cupboard中初始化 Bowl bowl3= new Bowl(3);,此时,输出结果为:Bowl(3)。(虽然bowl3在bowl4 和bowl5前面,但是却在之后初始化。。)

2.4.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

所以在执行完成static Cupboard cupboard = new Cupboard();后,输出结果为:

Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)

第三步:执行main函数的打印,输出:Init3.main()

第四步:执行 new Cupboard();(这里不执行静态成员变量bowl4 和bowl5,是因为已经被初始化,不需要在执行)

4.1.在Cupboard中初始化 Bowl bowl3= new Bowl(3);,此时,输出结果为:Bowl(3)。

4.2.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

输出结果:

Bowl(3)
Cupboard
f1(2)

第五步:执行main函数的打印,输出:Init3.main()

第六步:执行 new Cupboard();(这里不执行静态成员变量bowl4 和bowl5,是因为已经被初始化,不需要在执行)

6.1.在Cupboard中初始化 Bowl bowl3= new Bowl(3);,此时,输出结果为:Bowl(3)。

6.2.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

输出结果:

Bowl(3)
Cupboard
f1(2)

第七步:执行 table.f2(1); 输出:f2(1)

第八步:执行cupboard.f3(1); 输出:f3(1)

小节:初始化顺序先是静态对象(前提是该对象没有被初始化),然后是非静态对象。

(3)静态块初始化

在类中使用 static{….} 表示静态块,将在使用该类之前的数据初始化。

静态块与静态变量一样,只初始化一次。并且,执行顺序是按照位置从上往下执行,即:静态块与静态方法优先级相同。

触发条件:

1.首次生成这个类的对象;

2.首次访问属于这个类的静态成员。

class StaticBlock
{
    public static String s = "StaticBlock";

    static
    {
        System.out.println("StaticBlock.enclosing_method()");
    }
}

class InvokeStaticBlock
{
    public static void main(String[] args)
    {
        new StaticBlock(); // 生成对象的引用
        String ss = StaticBlock.s; // 使用该对象的静态成员
    }
}

 

总结:

对象创建流程:

1.当创建对象实例时,会去执行构造函数(构造函数可以看成是静态方法),Java解释器必须找到类路径,以定位到该类的.class文件;

2.加载class文件,并初始化所有静态数据。因此,静态初始化只有在class对象首次加载时执行一次,后面再次加载不再执行初始化操作;

3.创建对象时,会在堆上分配足够的存储空间;

4.这块存储空间会被清零,将基本类型数据附上初始值,引用类型置为null;

5.执行所有出现与字段定义处的初始化动作,即如果字段有初始值,即修改默认初始值,赋于新值;

6.执行构造函数。

时间: 2024-10-15 12:57:45

Java学习笔记二:初始化(二)的相关文章

Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门 Java提供的三大类网络功能: (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置.利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端. (2)Socket:又称"套接字",用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务).在客户/服务器网络中,当客

JAVA学习笔记(三十二)- 字符流 FileReader & FileWriter

标题 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream;

Java学习笔记之多线程二

看到一篇讲线程的故事性文章,觉得很有意思,很佩服作者能这么生动地讲述出来,点击可跳转阅读此文章:<我是一个线程> 继续我的笔记中总结 - - 理解线程安全问题: 下面是书上看到的卖票例子:模拟3个窗口同时在售10张票. 上篇博文笔记总结了多线程创建的两种方式,那我们就分别以这两种实现多线程的方式来解决这个场景. 使用继承于Thread类的方式 上Demo: class SaleTicket extends Thread { int num = 10; // 票数 public SaleTick

黑马程序员——JAVA学习笔记十三(高新技术二)

8,    注解 Annotation(注解)是JDK5.0及以后版本引入的. 注解是以 @注解名 的形式标识 注解不会影响程序语义,只作为标识 注解是新的类型(与接口很相似),它与类.接口.枚举是在同一个层次,它们都称作为java的一个类型(TYPE). 它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释. 它的作用非常的多,例如:进行编译检查.生成说明文档.代码分析等 注释类型 是一种特殊的接口 用 @interface 声明如 [email prote

JAVA学习笔记(五十二)- 开发DAO层的经典实现

StudentDAO接口,定义学生相关的操作 /* * StudentDAO接口,定义学生相关的操作 */ public interface StudentDAO { //添加学生 public void addStudent(Student stu); //删除学生 public void deleteStudent(int id); //修改学生 public void updateStudent(Student stu); //查询所有学生 public List<Student> ge

Java学习笔记—多线程(二)

Java线程常用方法总结 1.join()方法 join -- 让一个线程等待另一个线程完成才继续执行.如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行. public class MyRunnable implements Runnable{ @Override public void run() { for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getN

java学习笔记(十二)多线程编程

并发编程:可以让多个任务同时运行的编程方式. 进程:一个正在运行的程序,有自己独立的一块内存空间,每一个进程的内部数据和状态都是完全独立的.可同时运行两个或更多的程序. 线程:每一个任务称为一个线程,在一个程序内运行多线程的程序称为多线程程序. 线程是进程内部单一的一个顺序控制流,是最小处理单位. 创建线程: 1.继承Thread类,重写run()方法,在run()方法中编写要执行的代码. 先创建Thread对象,打点调用start()启动线程. 2.实现Runable接口,只有run()方法.

JAVA学习笔记(四十二)-生产者消费者模型

wait().notify() /* * wait().notify() * * 1.两个方法都只能在synchronized代码块中执行,因为要对持有锁的线程操作,只有同步中才有锁 * 2.两个方法在操作同步中的线程时,必须要标识所操作线程持有的对象锁 * 3.等待和唤醒必须是同一个对象锁 */ public class Test05 { public static void main(String[] args) { MyThread3 mt=new MyThread3(); Thread

Java学习笔记二:初始化(一)

1.对象初始化 在使用 new 初始化对象时,系统通常使用默认的构造函数,这个构造函数没有返回值,格式为: public class InitializeTest { private int a; // 默认构造函数 public InitializeTest() { } // 自定义构造函数 public InitializeTest(int a) { this.a = a; } } 虽然在使用 new 创建实例时,返回了这个对象的引用,但是这个与没有返回值的void方法不同 //void方法

【Java学习笔记之二十六】深入理解Java匿名内部类

在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始化匿名内部类.匿名内部类使用的形参为何要为final. 一.使用匿名内部类内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 } 在这里我们看到使用匿名内部类我们必须要继承一个父类或者