• 《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. 更快的模式

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

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

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

    缺点:效率低,耗空间

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

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

  • 相关阅读:
    17、网卡驱动程序-DM9000举例
    16、NOR FLASH驱动框架
    15.1 linux操作系统下nand flash驱动框架2
    15、NAND FLASH驱动程序框架
    14、块设备驱动程序框架分析
    12.2 linux USB框架分析(详细注册match匹配过程)
    arm-linux-gcc: Command not found
    12、USB设备驱动程序
    POJ-2752 Seek the Name, Seek the Fame (KMP)
    POJ-2406 Power Strings (KMP)
  • 原文地址:https://www.cnblogs.com/hhhqqq/p/12588151.html
Copyright © 2020-2023  润新知