level6 对象简介-编写你自己的对象、生命周期、静态变量
程序员之路
你的任务 – 学习中级开发人员所需的技术。这些技术是什么?世界在不停地变化。我来给你一些忠告。查找一些在线发布的 Java 程序员职位空缺,并浏览职位要求。另外,我还建议你阅读布鲁斯·埃克尔的书‘Thinking in Java’(《Java 编程思想》)。
你的任务 – 学习设计模式并阅读迈克康奈尔的‘Code Complete’(《代码大全》)。提高代码质量,并培养自己的团队协作能力。你可能会给自己制定一条规则:每月读一本 IT 书。然后在四年内,你和同事的聪明程度将相差 50 本书。千万不要推迟这种学习,因为将来你很可能再也没有更多的空闲时间,尤其是当你组建家庭之后。
对象可见性和 null 引用
对象的生存期,即对象在内存中保留多长时间。
创建对象后,只要有一个变量正在存储其地址(至少有一个对该对象的引用),则该对象存在(存活)。如果不再有任何引用,则该对象死亡。
如果我们不再需要变量引用某个对象,可以将该变量设置为 null,或为其分配对另一个对象的引用。
对象的生存期
创建一个对象,
首先,Java 虚拟机分配创建对象所需的内存。
然后它创建一个对它的引用
然后初始化所有变量,调用构造函数。
垃圾收集器会处理不再被使用的Java对象
不要依赖 finalize() 方法来释放关键资源。 JVM 可能会调用它,也可能不会。
错误处理资源和误解如何清理不必要的对象会导致最令人不快的错误之一:内存泄漏。
垃圾回收器
Java 的垃圾回收功能,以及用于引用计数和分代的对象可访问性。
垃圾收集器与您的程序并行工作。 它不是您程序的一部分。 它单独运行。
在 Java 中,决定收集垃圾不是基于引用计数,而是基于将对象分为两种类型:可达和不可达。
如果一个对象被另一个可达对象引用,则该对象是可达的。
所有 Java 对象都存储在称为堆的特殊内存区域中。
所有的对象都可以分为两种类型:简单对象和“长寿命对象”
当这个区域的空间用完时,一个初始的“快速”垃圾收集开始。不得不说垃圾收集器非常聪明。它根据堆是否有更多垃圾或更多活动对象来选择算法。如果几乎所有对象都是垃圾,收集器会标记活动对象并将它们移动到另一个内存区域。然后当前区域被完全清除。如果垃圾不是很多,而且堆中大部分是存活对象,则收集器标记垃圾,清除它,并将其他对象打包在一起。我们说 ”一个生存空间。
一个生存空间,又分为几代,如果一个对象在一轮垃圾回收中幸存下来,那么它就在“第 1 代”中;如果为 5,则为“第 5 代”。伊甸园和生存空间共同形成一个区域,称为年轻代。除了年轻代,堆还有一个内存区域叫做老年代。这正是在多轮垃圾收集中幸存下来的长寿命对象最终所在的区域。将它们与所有其他对象分开是有好处的。
全垃圾回收只有在老年代满时才会进行,即程序中有太多的长寿命对象,以至于没有足够的内存。这一过程涉及多个内存区域。一般来说,它涉及Java机器创建的所有对象。当然,这需要更多的时间和资源。这正是单独存储长期存在的对象的决定。
当其他区域空间不足时进行“快速垃圾收集”。
这只涉及一个领域,这使得它更快、更高效。最后,当甚至长寿命物体的区域被完全填满时,完全垃圾收集被触发。
因此,收集器仅在无法避免时才使用“最重”的工具。
这是堆结构和垃圾收集的直观表示:
###########未完待续
使用 finalize 终结对象
Java 虚拟机在销毁对象之前调用 finalize() 方法。该方法用于释放系统资源或执行其他清理任务。实际上,此方法与 Java 中的构造方法完全相反(构造方法是用于创建对象的)。
Object 类包含 finalize() 方法,这意味着所有其他类都是如此(因为所有 Java 类都是从 Object 类派生的)。你可以直接在类中实现自己的 finalize() 方法。
但是,你应该知道 Java 虚拟机决定是否调用此方法。通常,在方法内部创建并在方法完成时声明为垃圾的对象会立即销毁,而无需调用 finalize()。此方法更像是备份,而不是可靠的解决方法。最佳选择是在对象仍处于存活状态时释放所有系统资源(通过将对其他对象的引用设置为 null)。稍后,我将详细介绍此方法的优点和细微差别。到目前为止,你只需了解两件事:有这样一种方法,并且(惊喜!)这种方法并不总是被调用。
对象生存期
在 Java 中,很难意外销毁某个对象。如果你引用了某个对象,则该对象处于存活状态。
你不能更改对对象的引用,也不能增加或减少这些引用。另外,你也不能创建对某个对象的引用。你只能对引用赋值或将其设置为 null。
static 变量和方法
static 方法无法处理非 static 方法或非 static 变量!
优点:
首先,我们不必传递对象引用即可使用 static 方法和变量。
第二,有时需要只有一个变量副本。例如,System.out(System 类的 static out 变量)。
第三,有时你需要先调用一个方法,然后才能创建对象。
你为什么认为 main() 方法是 static?它是 static,因此程序员可以在任意对象创建之前,在将类加载到内存后立即调用它。
除了 static 方法,还有 static 类。
static变量使用,类.static变量