Java编程思想 第五章 初始化与清理(一)

第5章 初始化与清理

    • 5.1 用构造器确保初始化
    • 5.2 方法重载
      • 5.2.1区分重载方法
      • 5.2.2 涉及基本类型的重载
      • 5.2.3 以返回值区分重载方法
    • 5.3 默认构造器
    • 5.4 this关键字
      • 5.4.1 在构造方法中调用构造方法
      • 5.4.2 static的含义
    • 5.5 清理:终结处理和垃圾回收
      • 5.5.1 finalize()的用途
      • 5.5.2 你必须实施清理
      • 5.5.3 终结条件
      • 5.5.4 垃圾回收器如何工作

5.1 用构造器确保初始化

1.在创建对象时,为对象分配存储空间,编译器调用相应的构造器。
2.构造器的名字必须与类名完全相同。
3.在java中 初始化与创建捆绑在一起,两者不能分离。
4.构造器没有返回值,与返回值为空不同

不写构造方法会有有默认的一个无参的构造方法

public class AAA {

    public AAA() {}
}

5.2 方法重载

为了让方法名相同而形式参数不同的构造器同时存在,必须用到方法重载。

5.2.1区分重载方法

重载的方法参数类型列表独一无二

@Slf4j
public class AAA {

    public AAA() {
        log.info("hello AAA()");
    }
    
    public AAA(String  name) {
        log.info("hello AAA(i)"+name);
    }
}

5.2.2 涉及基本类型的重载

基本类型 不能是包装类型Integer,Double会提示错误
1.byte 1字节(8位)
2.boolean 1字节(8位)
3.short 2字节(16位)
4.char 2字节(16位)
5.int 4字节(32位)
6.float 4字节(32位)
7.long 8字节(64位)
8.double 8字节(64位)

较小类型会被自动转换为较大的类型,反之需要强制类型转换

	void printInt(int value){
		System.out.println("print(int value),"+value);
	}
	void printDouble(double value){
		System.out.println("print(double value),"+value);
	}
	@Test
	void test(){
		short valueShort = 5;
		int valueInt = 5;
		double valueDouble = 5.0;
		printInt(valueShort);
		printInt((int)valueDouble);

		printDouble(valueShort);
		printDouble(valueInt);
	}

在这里插入图片描述
顺序
byte—short—int—long—float—double
char—int—long—float—double
int—long—float—double
short—int—long—float—double
long—float—double
float—double
例子5.2.2-1在最后

5.2.3 以返回值区分重载方法

这是不行的,因为很有可能直接用 f(x)这种方式调用方法,编译器无法区分出调用的函数。

5.3 默认构造器

就是无参的构造方法,没有,编译器会自动创建
如果你自家创建了一个有参数的构造函数,编译器不会再创建。

5.4 this关键字

public class Person {
    public void eat(Apple apple){
        Apple peeled = apple.getPeeled();
        System.out.println("Yummy "+peeled.getPeel());
    }
}

@Data
public class Apple {

    private String peel ;

    public Apple(){
        this.peel= "hasPeel";
    }
    Apple getPeeled(){
        System.out.println("Apple getPeeled now peel:"+this.getPeel());
        return Peeler.peel(this);
    }
}

public class Peeler {
    static Apple peel(Apple apple){
        apple.setPeel("noPeel");
        System.out.println("Peeler peel apple peel:"+apple.getPeel());
        return apple;
    }
}

@Test
void test(){
	new Person().eat(new Apple());
}


在这里插入图片描述
Peeler.peel(this) 自身传递给外部方法

5.4.1 在构造方法中调用构造方法

public class Flower {
  private int petalCount = 0;
    private String s = new String("null");

    Flower(int petals) {
        petalCount = petals;
        System.out.println( "Constructor w/ int arg only, petalCount= "+ petalCount);
    }
    Flower(String ss) {
        System.out.println("Constructor w/ String arg only, s=" + ss);
        s = ss;
    }
    Flower(String s, int petals) {
        this(petals);
//!    this(s); // Can't call two!
        this.s = s; // Another use of "this"
        System.out.println("String & int args");
    }
    Flower() {
        this("hi", 47);
        System.out.println("default constructor (no args)");
    }
    void print() {
//!    this(11); // Not inside non-constructor!
        System.out.println("petalCount = " + petalCount + " s = "+ s);
    }
    public static void main(String[] args) {
        Flower x = new Flower();
        x.print();
    }
} ///:~

this(petals)构造方法必须在起始
this.s = s; 参数s和数据成员s同名,用this.s来代表当前数据成员

5.4.2 static的含义

5.5 清理:终结处理和垃圾回收

垃圾回收器只知道释放由new分配的内存
可以定义finalize()方法
当垃圾回收器准备好释放对象占用的存储空间,首先调用finalize()方法,在下次垃圾回收动作发生时,才会真正回收对象占用的内存。

1.对象可能不被垃圾回收
2.垃圾回收并不等于“析构”

5.5.1 finalize()的用途

3.垃圾回收只与内存有关

通过某种创建对象方式以外的方式为对象分配了存储空间,但Java中一切皆为对象。
这种特殊情况主要发生在使用“本地方法”,即调用非Java代码
不要过多的使用finalize()

5.5.2 你必须实施清理

无论是垃圾回收还是终结都不保证一定发生
以本人浅薄的汉语造诣是完全看不懂他到底在翻来覆去的说些什么,反正就是不用finalize()

5.5.3 终结条件

@Data
public class Book
{
    private String name ;
    private boolean checkedOut  = false;
    public Book( String name,boolean checkedOut){
        this.name = name;
        this.checkedOut = checkedOut;
    }
    public void checkIn(){
        checkedOut = false;
    }
    protected void finalize(){
        System.out.println(""+this.name+":finalize()");
        if(checkedOut){
            System.out.println("忘记checkIn  "+this.name);
        }
    }
}
@Test
void testFinalize(){
	Book novelOne = new Book("novelOne",true);
	novelOne.checkIn();
	new Book("novelTwo",true);
	Book novelThree = new Book("novelThree",true);
	System.gc();

}

在这里插入图片描述

novelTwo没有定义引用,调用了finalize方法,这样

5.5.4 垃圾回收器如何工作

1.引用记数
2.停止-复制
先暂停程序的运行,将所有或者的对象从当前堆复制到另一个堆
3.标记-清扫
遍历所有引用,标记存活对象。全部标记后,清理没有标记的对象。

参考:
Java编程思想读书笔记(一)第1~13、16章

例子5.2.2-1

public class PrimitiveOverloading {
    static void prt(String s) {
        System.out.println(s);
    }
    void f1(char x) { prt("f1(char)"); }
    void f1(byte x) { prt("f1(byte)"); }
    void f1(short x) { prt("f1(short)"); }
    void f1(int x) { prt("f1(int)"); }
    void f1(long x) { prt("f1(long)"); }
    void f1(float x) { prt("f1(float)"); }
    void f1(double x) { prt("f1(double)"); }

    void f2(byte x) { prt("f2(byte)"); }
    void f2(short x) { prt("f2(short)"); }
    void f2(int x) { prt("f2(int)"); }
    void f2(long x) { prt("f2(long)"); }
    void f2(float x) { prt("f2(float)"); }
    void f2(double x) { prt("f2(double)"); }

    void f3(short x) { prt("f3(short)"); }
    void f3(int x) { prt("f3(int)"); }
    void f3(long x) { prt("f3(long)"); }
    void f3(float x) { prt("f3(float)"); }
    void f3(double x) { prt("f3(double)"); }

    void f4(int x) { prt("f4(int)"); }
    void f4(long x) { prt("f4(long)"); }
    void f4(float x) { prt("f4(float)"); }
    void f4(double x) { prt("f4(double)"); }

    void f5(long x) { prt("f5(long)"); }
    void f5(float x) { prt("f5(float)"); }
    void f5(double x) { prt("f5(double)"); }

    void f6(float x) { prt("f6(float)"); }
    void f6(double x) { prt("f6(double)"); }

    void f7(double x) { prt("f7(double)"); }

    void testConstVal() {
        prt("Testing with 5");
        f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
    }
    void testChar() {
        char x = 'x';
        prt("char argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testByte() {
        byte x = 0;
        prt("byte argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testShort() {
        short x = 0;
        prt("short argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testInt() {
        int x = 0;
        prt("int argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testLong() {
        long x = 0;
        prt("long argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testFloat() {
        float x = 0;
        prt("float argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    void testDouble() {
        double x = 0;
        prt("double argument:");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    }
    public static void main(String[] args) {
        PrimitiveOverloading p =
                new PrimitiveOverloading();
        p.testConstVal();
        p.testChar();
        p.testByte();
        p.testShort();
        p.testInt();
        p.testLong();
        p.testFloat();
        p.testDouble();
    }

}

你可能感兴趣的:(java编程思想)