面向对象
Java 是一种面向对象的编程语言。在 Java 中,一切都是对象,每个对象都有一组属性和方法。通过类来定义对象的属性和方法,一个类可以创建多个对象,每个对象都具有相同的属性和方法,但是它们的属性值可以不同。
Java中的面向对象编程主要包括以下几个方面:
- 封装:将对象的属性和方法封装在一起,通过访问控制修饰符(public、private、protected)来限制对属性和方法的访问,从而保证数据的安全性和一致性。
- 继承:通过继承,子类可以继承父类的属性和方法,并可以添加自己的属性和方法,实现代码的复用和层次化设计。
- 多态:Java中的多态指的是同一个方法可以根据不同的对象调用出不同的行为。Java中的多态主要包括方法重载和方法重写。
- 抽象:抽象是将对象的共同特征提取出来,形成抽象类或接口,从而达到代码复用的目的。
面向对象编程使得程序的设计更加灵活和可维护性更高,使得代码更加易于扩展和重用。
对象在内存中的运行机制
对象在内存中的运行机制可以分为两个方面,即对象的创建和对象的销毁。
对象的创建
- 在堆内存中为对象分配一块内存空间。
- 分配内存后,调用该对象的构造方法进行对象的初始化,例如对象的属性赋值。
- 对象初始化后,返回该对象的引用,通过引用来访问对象的方法和属性
对象的销毁
对象不再被引用时,会触发Java虚拟机中的垃圾回收机制进行对象的销毁。垃圾回收机制会对所有不再被引用的对象进行标记,并将这些对象的内存空间释放回堆内存中,以供其他对象使用。
虚拟机中的垃圾回收机制采用的是自动化的方式,程序员不需要手动管理内存,这种机制使得Java程序的编写更加简单和安全。
对象引用是一个指向对象内存地址的指针,当对象引用被赋值为null时,表示该引用不再指向任何对象,这也是Java中的一种常用的对象销毁方式。
如何判断对象不再被引用
判断一个对象是否不再被引用有两种方法:
- 引用计数法
引用计数法是一种最简单的垃圾回收算法。它的基本思路是给每个对象记录一个引用计数器,每当有一个新的引用指向该对象时,计数器就加一,当引用失效时,计数器就减一。当计数器为0时,表示该对象不再被引用,可以被回收。
但是引用计数法有一个致命的缺点,就是无法处理循环引用的情况。当两个对象相互引用时,它们的引用计数器永远不会为0,导致这些对象无法被垃圾回收,从而出现内存泄漏的问题。
Java虚拟机并没有采用引用计数法来进行垃圾回收。
- 可达性分析法
Java虚拟机采用的是可达性分析法来进行垃圾回收。它的基本思路是通过一些根节点来寻找所有的存活对象。根节点包括虚拟机栈中引用的对象、类静态属性引用的对象和常量引用的对象。
可以把Java中所有的对象看作是一个有向图,图中每个节点表示一个对象,每个引用表示一条有向边,指向被引用的对象。通过这个图,可以找到所有被根节点所引用的对象,将这些对象标记为存活对象,而没有被标记的对象就是垃圾对象。从这些根节点开始,通过引用链遍历所有的对象图,将所有被遍历到的对象标记为存活对象,没有被标记的对象即为垃圾对象。
在示意图中,存在三个垃圾对象:F、G、H。这些垃圾对象没有被任何根节点引用,也不会被遍历到,因此它们将会被垃圾回收器回收。
因此存活对象为:A、B、C、D、E;垃圾对象为:F、G、H。
【总结】:可达性分析法可以解决循环引用的问题,因为Java虚拟机可以检测到对象之间的引用关系,从而避免出现内存泄漏的问题。