• Java 对象的初始化和清理


    初始化和清理

    1. 用构造器确保初始化

    初始化需要解决的两个问题:

    1. 任何名字都可能与类的某个成员名称冲突
    2. 调用构造器是编译器的责任,所以必须让编译器知道调用哪个方法

    在Java中采用这种方法:构造器与类有相同的名称

    • 构造器不需要返回值
    • 不接受任何参数的构造器叫默认构造器,也叫无参构造器
    • 一个类,如果我们没有提供构造器,会有一个无参构造器。如果我们自定义了构造器,那么会顶替掉默认构造器,如果还想要无参构造器,得自己手动添加。

    2. 方法重载

    现在我们有多种属性的初始化需求,那么想用多种方式创建一个对象该怎么办?

    重载

    2.1 区分重载方法

    要是几个方法有相同的名字,那么你指的是哪一个呢?

    ​ 规则:每个重载的方法都必须有一个独一无二的参数列表。参数顺序不同,也算不同

    方法返回值不同,其他相同,即返回参数不同算重载吗?

    ​ 如果调用方法时,不保存返回值,那么编译器不知道该调用哪个方法,所以编译不通过,不算。

    2.2 涉及基本类型的重载

    基本类型能从一个“较小”的类型自动提升至一个“较大的”类型。那么将一个较小类型传入到参数为较大类型的方法,会怎么样呢?

    1. 如果传入类型小于方法中声明的参数类型,实际数据类型会提升。char略有不同,会直接提升到int
    2. 如果传入类型大于方法中声明的参数类型,那就必须强转了。

    3. this关键字

    如果想在方法内部获得当前对象的引用,那么你需要this关键字

    3.1 在构造器中调用构造器

    3.2 static

    static方法就是没有this的方法

    4. 终结处理和垃圾回收

    Java有自己的垃圾回收机制,为啥还要了解垃圾回收呢?

    如果通过JNI创建了一些对象,那么这些对象Java是无法控制的,你怎么做?

    4.1 finalize()

    为了释放一些特殊的内存(如:natvie方法),java允许在类中定义一个名为finalize()的方法。

    原理:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作是,才会真正回收对象占用的内存。

    因此:我们就可以在finalize()中,调用free()等释放内存的方法。

    如果对象中含有其他对象(普通java对象),finalize应该明确释放那么对象吗?

    不,对于java中的对象,不管是如何创建的,垃圾回收器都会负责释放对象占据的内存,最好要在finalize中对一般java对象做释放操作。

    4.2 垃圾回收器如何工作

    1. 首先理解其他系统中的垃圾回收机制
      • 引用计数:每个对象都有一个引用计数器,有引用连接至对象那么计数器加一,当离开引用域或者置为null将计数器减一,当发现某个对象的引用计数为零的时候,就释放对象占用的内存。存在缺陷:如果对象间存在循环引用,那么应该被回收的对象,引用计数却不为零。
    2. Java中垃圾回收机制:自适用垃圾回收机制。
      • 停止-复制:先停止程序的运行,然后将所有活着的对象复制到另一个堆,没有被复制的全部是垃圾。缺点
        1. 需要额外的操作空间(两个堆)
        2. 程序稳定后,只会产生少量的垃圾,甚至没有垃圾,直接复制的话,这很浪费。
      • 标记--清扫:从堆栈和静态存储区出发,遍历所有引用,进而找到所有存活的对象。每当找到一个活的对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有标记工作完成,才会开始清理动作。剩下的对空间是不连续的,如果垃圾回收器希望得到连续的空间,就得重新整理剩下的对象。

    Java虚拟机会监视资源,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”;同样,如果堆空间出现很多碎片就会切换回“停止-复制”方式。这就是“自适用”技术。

    6. 成员初始化

    Java尽力保证:所有变量在使用前都能得到恰当的初始化。

    6.1 初始化顺序

    成员变量的初始化,放在构造器初始化之前。比如:成员变量是有初始值默认值的,经过构造器赋值才变为新的值。所以 成员变量初始化--->构造器初始化

    • 如果有多处成员变量初始化呢?

      成员变量按上下顺序初始化后,开始构造器中的初始化

    • 静态数据的初始化

      静态对象先于非静态。

    6.1.2 静态代码块和非静态实例初始化

    Child继承自Parent,两者的初始化顺序。子类可能会用到父类中的属性,所以父类中的初始化会先于子类,但是Static比较特殊,先于两者的所有其他非静态属性。

    顺序 代码块
    1 Parent static block
    2 Child static block
    3 Parent block
    4 Parent constructor
    5 Child block
    6 Child constructor
  • 相关阅读:
    Spring>autoWire
    hibernate>多对多关联映射
    Hibernate>一级缓存
    Hibernate>component映射和复合主键映射
    Struts2>类型转换
    hibernate>继承
    hibernate>悲观锁和乐观锁
    Spring>Bean的作用域
    Struts2>defaultactionref
    数据库的隔离级别
  • 原文地址:https://www.cnblogs.com/hitomeng/p/10942501.html
Copyright © 2020-2023  润新知