java编程思想笔记中级篇第5-12、14、15、17章(未完。。)

第5章初始化与清理

5.1 用构造器确保初始化

  1. 当代码执行到new Test()时,将会给对象分配内存,并调用相应的构造器。

5.2方法重载

  1. 如果想用多种方式创建一个对象,那么就用到方法重载,一个默认构造器,一个有参构造器。
  2. 方法名相同、参数列表不同(可以顺序不同)。

5.3默认构造器

  1. 如果类中没有构造器,则编译器会创建一个默认构造器。如果有(无论有参无参),编译器都不会创建。

5.4this关键字

  1. 在方法内部获得当前对象的引用。this是编译器传入的。直接调用。this可以省略

5.5在构造器中调用构造器

public class ThisTest {
    private int code;
    private String message;
    private T data;
    public ThisTest(int code,String message){
        this(code,message,null);
    }

    public ThisTest(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

static的含义: static方法是没有this的方法。所以无需创建对象就能使用。

5.5终结处理和垃圾回收

  1. 当一个对象不是new出来的(比如使用了本地方法里面的c语言中的malloc()函数来分配存储空间),但是在内存中获得了一块区域。垃圾回收器是不能回收的(垃圾回收器只回收new出来的对象)。所以有了finlize()方法。该方法会调用c语言的free()方法释放内存。

5.6成员初始化

  1. 所有变量在使用前都能得到恰当的初始化。(手动+自动)
  2. 初始化会自动进行,它会在构造器被调用之前发生
public class ThisTest {
    private int i;
    public ThisTest(int i){
        i = 10;
    }
}

i首先会被置为0,然后执行构造方法,然后变成10.

5.7构造器初始化

5.7.1初始化顺序

在类的内部:变量(基本类型和引用类型)会按照定义的顺序进行初始化,没有行的先后顺序,总是先于任何方法(包括构造器)调用之前。
下面是代码示例:

public class Window {
    public Window(int marker){System.out.println("window:"+marker);}
}
public class House {
    private Window window1 = new Window(1);
    public House(){
        System.out.println("House()");
        w3 = new Window(3);
        System.out.println(i);
    }
    private Window w2 = new Window(2);
    void f(){System.out.println("f()");}
    int i;
    Window w3 = new Window(3);
}
public class Test {
    public static void main(String[] args) {
        House house = new House();
        house.f();
    }
}

结果:
window:1
window:2
window:3
House()
window:3
0
f()

5.7.2静态数据的初始化
  1. 无论创建多少对象,(static)静态数据只占一份内存区域。
  2. 先初始化静态对象,再初始化非静态对象,静态初始化只有在必要时才会初始化。
    下面有个小例子:看完就会明白静态数据是何时初始化的
public class Bowl {
    public Bowl(int marker){
        System.out.println("marker:"+marker);
    }
    void f1(int marker){ System.out.println("f1::"+marker);}
}
public class Table {
    static Bowl bowl = new Bowl(1);
    public Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker){ System.out.println("f2:"+marker); }
    static Bowl bowl2 = new Bowl(2);
}
public class Cupboard {
    public Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    public Cupboard(){
        System.out.println("Cupboard");
        bowl4.f1(2);
    }
    void f3(int marker){ System.out.println("f3:"+marker); }
    static Bowl bowl5 = new Bowl(5);
}
public class Test {
    public static void main(String[] args) {
        System.out.println("creat new cupboard in main");
        new Cupboard();
        System.out.println("creat new cupboard in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

结果:
marker:1
marker:2
Table()
f1::1
marker:4
marker:5
marker:3
Cupboard
f1::2
creat new cupboard in main
marker:3
Cupboard
f1::2
creat new cupboard in main
marker:3
Cupboard
f1::2
f2:1
f3:1

  1. 对象的创建过程,以Dog类为例
    1.当首次创建Dog对象时,或首次访问Dog类的静态方法或静态域,java解释器先查找类路径,定位Dog.class文件。
    2.载入Dog.class,有关静态初始化的所有动作都在此时执行。此时还没有创建对象,因此静态初始化只在Class文件首次加载时进行一次。
    3.当用new Dog()创建对象时,首先将在堆上的Dog对象分配足够的存储空间。
    4.这块存储空间会被清0、意思就是基本数据类型初始化、引用类型设置为null。
    5.执行所有出现于字段定义出的初始化动作。
    6.执行构造器。
5.7.3静态代码块
public class Cup {
    public Cup(int marker){ System.out.println("Cup:"+marker); }
    void f(int marker){ System.out.println("f:"+marker); }
    static Cup cup = new Cup(999);
}
public class Cups {
    static Cup cup1;
    static Cup cup2;
    static Cup cup3 = new Cup(3);
    static {
        cup1 = new Cup(1);
        cup2 = new Cup(2);
    }
    Cups(){ System.out.println("Cups()"); }
    static Cup cup4 = new Cup(4);
}
public class Test {
    public static void main(String[] args) {
        Cups.cup1.f(99);
    }
    static { System.out.println("test main"); }
}

5.7.4非静态实例初始化

没有static的{}代码块:初始化每一个对象的非静态变量。

public class Mug {
    public Mug(int marker){ System.out.println("Mug:"+marker); }
    void f(int marker){ System.out.println("f:"+marker); }
}
public class Mugs {
    Mug mug1;
    Mug mug2;
    {
        mug1 = new Mug(1);
        mug2 = new Mug(2);
    }
    Mugs(){ System.out.println("Mugs()"); }
    Mugs(int marker){ System.out.println("Mugs:"+marker); }
    public static void main(String[] args) {
        System.out.println("Mugs main");
        new Mugs();
        System.out.println("new Mugs completed");
        new Mugs(1);
        System.out.println("new Mugs(1) completed");
    }
}

5.8数组初始化

  1. 一维:int[],二维:int[][]
  2. 编译器不允许指定数组的大小。
  3. 初始化:int[] a = new int[10]
  4. 可变参数列表
public class Test {
    public static void main(String[] args) {
        f("a","v");
        f("bb","cc","dd");
    }

    public static void f(String... arg){
        for (String temp:arg){
            System.out.println(temp);
        }
    }
}

结果:
a
v
bb
cc
dd

5.9枚举类型

  1. enum
public enum Spiciness {
    NOT, MILD, MEDIUM, HOT, FLAMING
}
public class Test {
    public static void main(String[] args) {
        Spiciness medium = Spiciness.MEDIUM;
        System.out.println(medium);
    }
}

结果:
MEDIUM
分析:
上面创建了一个名为Spiciness的枚举类型,有5个具名值。
要想使用枚举,需要创建一个该类型的引用(Spiciness.MEDIUM),并将其赋值给某个实例(Spiciness medium = Spiciness.MEDIUM; )

  1. 当创建枚举时,会自动添加toString方法,还有ordinal()方法(用来表示某个特定枚举常量的声明顺序,以及static values()的用法)。
public class Test {
    public static void main(String[] args) {
        for (Spiciness s : Spiciness.values()){
            System.out.println(s+":"+s.ordinal());
        }
    }
}

结果:
NOT:0
MILD:1
MEDIUM:2
HOT:3
FLAMING:4

  1. enum的新特性:在switch中使用,switch与enum是绝佳的配合。
public class Test {
    Spiciness spiciness;
    Test(Spiciness spiciness){
        this.spiciness = spiciness;
    }
    void desc(){
        switch (spiciness){
            case MEDIUM:
                System.out.println("medium");
                break;
            case HOT:
                System.out.println("hot");
                break;
            default:
                System.out.println("hello");
        }
    }
    public static void main(String[] args) {
        Test test = new Test(Spiciness.MEDIUM);
        Test test1 = new Test(Spiciness.HOT);
        Test test2 = new Test(Spiciness.FLAMING);
        test.desc();
        test1.desc();
        test2.desc();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值