《Java编程思想》05.初始化与清理

  • 编程代价高昂的主因:不安全的编程方式
  • C++引入构造器(constructor),对象被创建时自动调用的特殊方法
  • Java也采用构造器,同时引入垃圾回收器

构造器确保初始化

  • 通过构造器,确保每个对象在被操作之前都能得到初始化
  • 构造器为什么要与类的名称相同?
    • 任何名字都可能与类的某个成员名称相冲突
    • 需要让编译器知道该调用哪个方法来初始化这个对象(调用构造器是编译器的责任
    • 实质上也就是沿用了C++的解决方法
  • 因此在编码风格(方法首字母小写)的角度上来看,构造器的命名是个例外
  • Java中,初始化与创建捆绑

方法重载

方法的重载能够减少语言的冗余性,倘若没有方法的重载,构造器也就难以实现,我们需要与编译器之间约定构造器方法的名称,让编译器知道调用哪个方法,由编码者来命名的话,便会有很多不同的名称,如果采用匹配的方案来实现的话,比如:类名为Car,将自己写的构造器命名为CarOne(),用类似匹配Car*的方式,如果写的方法一多,也就难免重复,带来诸多麻烦。总之:构造器是强制重载方法的另一个原因

重载方法的区分

  • 独一无二参数类型列表
    • 个数不同
    • 顺序不同 - 一般不这么做<-代码难以维护
    • 类型不同

以返回值类型区分重载方法

void f(){}
int f(){return 1;}

能否区分调用方法依赖于用户调用的情况:

int x = f();    //能够区分
f();            //无法区分  (为了副作用而调用)

根据方法的返回值来区分重载方法是行不通的

默认构造器

如果没有定义构造器,编译器会自动创建一个默认的构造器(“无参构造器”)

this关键字

class Banana { void peel(int i){/*...*/} }

public class test {
    
    public static void main(String[] args) {
        Banana a = new Banana();
        Banana b = new Banana();
        a.peel(1);
        b.peel(2);
    }
}

上述代码,peel()如何知道被a还是b调用?
编译器将“所操作对象的引用”作为第一个参数传递给peel()
所以实际上是:

Banana.peel(a, 1);
Banana.peel(b, 2);

这个引用是编译器引入的,为了能够在方法的内部获得当前对象的引用,设立专门的关键字:this

构造器中调用构造器

class Banana {
    private String name;
    private double price;

    Banana(double price){
        this.price = price;
    }

    Banana(String name, double price){
        this(price);
        this.name = name;
    }

    public void info(){
        System.out.println("name:" + name + ";price:" + price);
    }
}
  • 无法调用两个 <- 构造器必须置于最起始处

static的含义

  • 没有this的方法
  • static方法内不能调用非静态方法
  • 没有创建任何对象的前提下能调用static方法(仅通过类本身)
class Tool {
    public static void sayHi(){
        System.out.println("hello.");
    }
}
public class test {
    public static void main(String[] args) {
        Tool.sayHi();   //仅通过Tool类本身调用,而不是由Tool创建的对象
    }
}
/* Output:
hello.
*/

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

  • Java里的对象并非总是被垃圾回收
    • 对象可能不被垃圾回收
    • 垃圾回收不等于“析构”
    • 垃圾回收只与内存有关

    垃圾回收->回收程序不再使用的内存

Native Method 本地方法

垃圾回收器如何工作

  • 在堆上分配对象的代价十分高昂
  • Java的垃圾回收器能够提高对象的创建速度 -> 因此Java从分配空间的速度可以和其他语言从堆栈上分配空间的速度相媲美

一些垃圾回收机制:

  1. 引用计数

简单、慢

每个对象 一个 引用计数器,当有引用连接至对象,引用计数加1;垃圾回收器在含有全部对象的列表上遍历,发现某个对象的引用计数=0,就释放其空间

  1. 更快的模式

依据:任何“活”的对象 ---能追溯到---> 在堆栈或静态存储区之中的引用,在此区域遍历所有引用 ---能找到---> 所有的“活”的对象

如何处理找到的“活”的对象

  • 停止-复制
    先暂停程序的运行,将所有“活”的对象复制到另一个堆(旧地址需要映射到新地址)

缺点:效率低,耗空间

  • 标记-清扫
    找到活对象->标记,全部标记工作完成,清理开始,没有标记的对象被释放,重新整理剩下的对象(由于剩下的堆空间是不连续的)

在只产生少量垃圾的情况下,它的速度很快

原文地址:https://www.cnblogs.com/hhhqqq/p/12588151.html