7. 【创建和销毁对象】避免使用终结方法finalize

C#基础:Dispose()、Close()、Finalize()的区别详解 本篇文章是对c#中的Dispose()、Close()、Finalize()的区别进行了详细的分析介绍,需要的朋友参考下 立即下载

本文是《Effective Java》读书笔记第7条,其中内容可能会结合实际应用情况或参考其他资料进行补充或调整。


终结方法(finalize)通常是不可预测的,也是很危险的,因此一般情况下应该尽量避免使用终结方法。
对于C++程序猿来说,析构方法是再熟悉不过了,它常用来回收对象所占用资源,以及回收其他非内存资源等。但是我们通常会告诫C++转到Java的程序猿,“Java中的终结方法与析构方法是相当不同的”。
在Java中,回收对象所占用资源的事情交给垃圾回收器来执行了,而手动回收对象外资源的事情也通常交由try - finally来完成。

吐槽终结方法

并不保证及时性

首先要吐槽的一点就是,终结方法并不能保证被及时执行。从一个对象变为不可达,到它的终结方法被执行,中间所花费的时间是任意长的。所以,注重时效性的任务不应交由“不靠谱”的终结方法来完成。比如,使用完文件后将其关闭的动作如果放在终结方法中,那么一旦JVM延迟执行终结方法,那么会有大量的文件保留在打开状态,而文件是一种很有限的资源,从而会影响到程序的性能甚至准确性和健壮性。
通常终结方法由垃圾回收算法来执行,而这种算法在不同的JVM实现中会大相径庭。所以依赖终结方法的话,很可能会出现测试效果与实际应用效果不同的情况。在垃圾回收过程中的终结方法线程的优先级相对来说要低得多,所以交给它来执行的事情通常如同交代一件事给一个严重拖延症患者。

并不保证会执行

有时候当一个程序终止的时候,某些已经无法访问的对象上的终结方法根本没有被执行,这是完全有可能的。
System.gc和System.runFinalization这两个方法可以增加终结方法被执行的机会,但是不保证一定被执行。而唯一声称保证终结方法被执行的两个方法是System.runFinalizersOnExit和Runtime.runFinalizersOnExit,但由于两个方法都有致命缺陷,已经被废弃了。。。
看到这,估计你会怀疑当初的Java语言设计者为啥要放这么一个形同阑尾的鸡肋特性。这不仅是个重度拖延症患者,而且执行力也很成问题,如果你是公司老板,肯定不会用这样的员工吧。

继续吐槽

关于终结方法的劣迹其实还有可以扒出来一些。比如假设这样一个情形,如果终结方法中抛出未被捕获的异常,那么这种异常可以被忽略,并且该对象的终结过程都完不成了,就好像这个对象突然穿越到某个次元,处于破坏的状态,其他线程使用这种被破坏的对象的时候就不知道会发生什么奇怪的事情了。更糟糕的是,这种异常压根不会像正常的异常(怎么感觉措辞有点怪怪的。。。)将线程终止并打印出Stack Trace,甚至连警告都看不到。
而且,终结方法由一个非常严重的性能损失,用终结方法创建和销毁对象会慢几十倍几百倍。。。

那如何正确地终止呢?

显式的终止方法

如果类中对象封装的资源确实需要终止,只需要提供一个显示的终止方法,并要求该类的使用方在每个实例不可用的时候调用这个方法即可。
这种例子其实比比皆是,比如InputStream、OutputStream和java.sql.Connection等类的close方法。

结合try - finally

显式的终止方法通常要结合try - finally结构来使用,以确保及时终止。在finally子句中调用显式的终止方法,可以保证即使在try块中使用该对象的时候抛出异常,然后能够正确执行终止方法。
当然,Java7之后,try with resources特性的加入使得这一过程更加容易和靠谱了。

如何正确使用终结方法呢?

声讨了这么多,终结方法有木有合法的使用途径呢?

“安全网”

这一条完全是本着“有比没有强”的原则来的,迟一点释放关键资源总比永远不释放要好吧,假设对象的使用者忘了调用显示的终止方法,那么这层安全网多少能够保证资源有较大概率是可以被释放的。而且如果终结方法发现资源没有被终止,则应该在日志中记录一条警告,表示由一个Bug,应该得到修复。
在FileInputStream、FileOutputStream、Timer和Connection等类中,都有终结方法,充当安全网的作用。

终止native资源

终结方法的第二种合理用途与对象的本地对等体(native peer)有关。本地对等体是一个本地对象(native object),普通对象(java object)通过本地方法(native method)委托给一个本地对象,因为本地对等体不是一个普通对象,所以垃圾回收器不知道它,当它的java对等体(也就是普通对象)被回收的时候,它不会被回收。
在本地对等体并不拥有关键资源的前提下,终结方法正是执行这项任务合适的工具。如果本地对等体拥有必须被及时终止的资源,那么该类就应该具有一个显式的终止方法,如前所述。
值得一提的重要一点是,“终结方法链”并不会自动执行。如果某个类有终结方法,并且子类覆盖了终结方法,子类的终结方法必须手工调用超类的终结方法。你应该在try块中终结子类,并在finally中调用超类的终结方法,这样能够保证即使子类的终结过程抛出异常,超类的终结方法也能够执行。如下所示:

//手动的终结方法链
@Override protected void finalize() throws Throwable {
    try {
        ... // 终结子类
    } finally {
        super.finalize();
    }
}

如果子类覆盖了超类的终结方法,但是忘了手工调用超类的终结方法,那么超类的终结方法将永远不会被调用到。要防范这样粗心大意或者恶意的子类是有可能的,代价就是为每个将被终结的对象创建一个附加的对象。将终结方法放到一个匿名的类中,该匿名类的唯一用途就是终结它的外围实例。该匿名类的单个实例被称为终结方法守卫者(finalizer guardian),外围类的每个实例都会创建这样一个守卫者。外围实例在它的私有属性中保存着一个对其终结方法守卫者的唯一引用,因此终结方法守卫者与外围实例可以同时启动终结过程,也就是当守卫者被终结的时候,它执行外围实例所期望的终结行为,就好像它的终结方法是外围对象上的一个方法一样。

// 共有类
public class Foo {
    ...
    // 终结守卫者
    private final Object finalizerGuardian = new Object() {
        @Override protected void finalize() throws Throwable {
            ... // 终结外围Foo对象
        }
    };
    ...
}

注意到,共有类Foo并没有终结方法(除了从Object中继承的一个无关紧要的外),所以子类的终结方法是否调用super.finalize并不重要。

总结

总之,除了以上两种用法之外,请不要使用终结方法。

【干货】SAP特殊库存:Q库存(项目库存)全解析,搞懂ETO模式的核心! 在 SAP 系统中, 阅读详情

相关推荐

数据中心GPU芯片性能参数速查表(Nvidia+国产算力卡)

本文提供了一份数据中心GPU芯片性能参数速查表,涵盖Nvidia与国产算力卡两大阵营。文章详细解读了算力、显存、互连技术及功耗等关键性能指标,并对比了A100、H100、昇腾910B等主流型号,旨在帮助用户根据AI训练、推理等实际场景,做出高效的硬件选型与成本评估决策。

a0b1c2d3的专栏 836

深入理解java的finalize

[b]目录[/b] 基本预备相关知识 对象的销毁过程 对象重生的例子 对象的finalize的执行顺序 何时及如何使用finalize 参考 [b]基本预备相关知识[/b] 1 java的GC只负责内存相关的清理,所有其它资源的清理必须由程序员手工完成。要不然会引起资源泄露,有可能导致程序崩溃。 2 调用GC并不保证GC实际执行。 3 finalize抛出的...

zhang_xzhi's blog 332

拌合楼管理软件开发(十一) 海康威视车牌识别摄像头安装调试,总算是跑通了。

/保存的文件个数这里之所以需要用到委托,直接更新textbox文本中的内容,以及复制picturebox的image会提示不是从齐创建的线程调用。

morsth的博客 4815

final、finally和finalize

简单的说一哈, final是修饰符,final修的类,不能被继承,修饰的方法不能被覆盖,修饰的属性如果没有在申明的地方赋值,那么就必须在构造方法里赋值,局部方法里不能用fanal修饰.finally是关键字,在处理异常的时候我们需要把每次必须执行的东西放到fianlly中,比如说,io流的关闭,session的关闭等等.finalize()是一个方法,当我们想手动调用垃圾回收机制的时候,调用sys

梵城专栏 512

第二十一篇: `man`, `tldr`, `explain` - 授人以渔的“终极指令”

我们已经一起学习了19个(组)关键命令,从nvidia-smi到kubectl。但这只是GPU运维武器库中的一小部分。技术日新月异,新的工具、新的参数会不断涌现。这个系列的真正目的,不仅是教会你使用这19件“兵器”,更是希望你掌握学习任何一件新兵器的方法论。这套方法论就是你的“终极指令”。授人以鱼不如授人以渔。至此,《GPU运维指令集:20个关键命令的战地手册》系列已全部完结。我们从nvidia-smi出发,一路探索了监控、诊断、容器、集群、网络、性能等各个维度的命令,最后用自动化脚本将它们串联,又用。

weixin_42587823的博客 1351

Transformer 时间序列预测实战

Transformer 时间序列预测实战

机器学习深度学习业余选手 743

Delphi常用内存管理函数

1.New、Dispose、GetMem、FreeMem New procedure New(var P: Pointer);:创建一个新的动态变量,并把指针P指向这个新创建的变量。分配的内存大小由P指针表示的类型决定。 Dispose procedure Dispose(var P: Pointer);:用来释放一指针变量所占用的内存地址。如使用{$I+},会产生一个EInvalidPo

kimifdw的专栏 3710

华为OD机试新系统真题【计算电动车续航里程】

华为OD机试 新系统真题【计算电动车续航里程】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【计算电动车续航里程】多语言题解。

qq_45776114的博客 781

Delphi 的结构体支持

Delphi 新的结构体初始化语法。

pcplayer的博客 1271

具身智能(40):主流 VLA 模型π₀

摘要: π₀是首款专为机器人设计的VLA(视觉-语言-动作)端到端基础模型,通过双阶段训练实现“感知-决策-执行”闭环。其创新点包括:1)FlowMatching技术实现连续平滑动作控制(精度0.3°);2)结合VLM预训练与多机器人实操数据,零样本任务完成率达76.4%,远超同类模型;3)支持模糊指令理解与动态场景适应(如遮挡识别)。开源版本涵盖不同规模模型,适用于工业装配、服务机器人等场景,在延迟(213ms)和稳定性(92%自主恢复率)上显著领先OpenVLA等竞品。

码农17年的博客 510

如何在Windows上安装Node-RED?

Node-RED 是一款基于流程的可视化编程工具,专注于物联网(IoT)和自动化应用的快速开发,其核心特点是通过拖拽节点构建数据流网络,实现低代码/无代码编程。

猿小白的博客 1171

JAVA中FileInputStream和FileOutputStream这两个字符流的用法

关于JAVA中文件字符流的用法

weixin_44131997的博客 394

物理AI重构自动驾驶供应链 | 传统Tier1盈利模式崩塌,纯算法/软硬一体双路线落地对比,助力智驾软件商业化与全场景模型迭代

2026年是自动驾驶物理AI规模化落地元年,行业彻底告别传统感知-预测-规划-控制的模块化分层开发范式,迈入以世界模型、物理规则推演、端到端动作生成为核心的全新技术阶段。不同于传统AI仅完成图像识别、目标检测的浅层感知任务,物理AI能够深度理解道路交通中的动力学约束、路面摩擦、车辆博弈、行人运动规律等真实物理逻辑,实现对复杂路况的时序推演与自主决策,从底层重构自动驾驶技术架构。技术迭代同步引发产业链颠覆性变革,沿用数十年的传统自动驾驶Tier1商业模式全面崩塌。

getusushu的博客 288

《Effective Java》阅读笔记7 避免使用终结方法

1.序 终结方法(Finalizer)是不可预知的,很多时候是危险的,而且一般情况下是不必要的。 Java 9 中终结方法已经被遗弃了,但它们仍被Java类库使用,清理方法替代了终结方法 比起终结方法,清理方法相对安全点,但仍是不可以预知的,运行慢的,而且一般情况下是不必要的。 学习过C++的同学看到终结方法(finalizer)应该马上就能想到C++中的析构函数(destructor)。 Java中的终结方法和C++中的析构函数类似,会在对象被垃圾回收之前执行,也就是对象被销毁之前执行。 在C++中,

weixin_41563161的博客 342

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

第7条:避免使用终结方法

  本条的意思是,让你尽量不要在你的类中覆盖finalize方法,然后在在里面写一些释放你的类中资源的语句。   至于为什么要避免覆盖并使用finalize呢,理由如下:     (1)finalize方法不能保证它能被及时的执行。    (2)finalize方法甚至都不会被执行。    (3)System.gc和System.runFinalization这两个方法只是能增加fi...

152

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Effective Java (7) - 避免使用终结方法

一. 基本概念 1. 所谓的终结方法其实是指finalize()。 2. Java的垃圾回收机制只负责内存相关清理,其他资源的清理(释放文件、释放DB连接)需要程序员手动完成。 3. 调用System.gc() 只是建议JVM执行垃圾回收(GC),但什么时候执行、是否要执行由JVM决定。 4. 用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。 5. 如果一个类实现了finalize方法,那么当JVM执行垃圾回收的时候,该方法一定会被调用。

技术人生 1646

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

《Effective Java》学习笔记——第1部分 创建对象和销毁对象的最佳实践

Effective Java》共有多个章节,每个章节提供了若干条建议或最佳实践,整理了对应章节关键的实践内容,用于自己后续代码开发过程中,参考对照,自查代码习惯,从而提升输出的代码质量。

weixin_37693760的博客 1144

如何销毁对象

在任何一个面向对象的语言中,这个对象销毁机制都是很重要的。因为如果对象不能够被及时的回收,那么很多没用的对象就仍然会占用内存地址。久而久之,就会导致内存耗竭,从而导致服务器当机。 在这个对象的销毁上,Java语言比其他面向对象的语言更胜一筹。因为其他面向对象的语言,需要在程序代码中手工回收废弃的对象。不过Java语言则不同。在Java语言中拥有一套完整的对象垃圾回收机制。即程序开发人员不需要...

yuyanqifei的专栏 1708

effective java —— 终结方法守卫者

effective java —— 终结方法守卫者

Java程序员的知识博客 760

Effective java 笔记 ---- 第八条 避免使用终结方法和清除方法

1. 终结方法(finalizer) 通常是不可预测的,也是很危险的,一般情况下是不必要的。使用终结方法会导致行为不稳定、性能降低,以及可移植性问题。当然,终结方法也有其可用之处,但根据经验,应该避免使用终结方法。在Java9 中用清除方法(cleaner) 代替了终结方法。清除方法没有终结方法那么危险,但仍然是不可预测、运行缓慢,一般情况下也是不必要的。 2. 终结方法和清除方法的缺点在于不能...

huanhuan8944172的专栏 870

【Effective Java】Ch2_创建销毁对象:Item7_避免使用finalize方法

Finalizer通常是不可预测的、危险的、不必要的。使用finalizer会导致不稳定的行为、低下的性能、以及可移植问题。Finalizer也有其可用之处,本文稍后会做介绍,但是作为一个首要法则,你必须避免使用finalizer。         C++程序员需要注意Java中的finalizer并不类似C++中的析构方法destructor。C++的析构方法是回收一个对象相关的资源的常用途径

Alpha's 学习笔记 2456

effective java(7) 之避免使用终结方法

effective java 之避免使用终结方法 1、终结方法其实是指finalize()。 2、为什么要避免终结方法 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要使用它的。 使用终结方法会导致行为不稳定,降低性能,以及可移植性的问题,不过终结方法也有其可用之处(后面介绍)。 在C++中存在着析构器(destructors)这种帮助回收

Eric的博客 422

【effective java】7.避免使用终结方法

1.whata)所谓的终结方法其实是指finalize()。b)Java的垃圾回收机制只负责内存相关清理,其他资源的清理(释放文件、释放DB连接)需要程序员手动完成。c)调用System.gc() 只是建议JVM执行垃圾回收(GC),但什么时候执行、是否要执行由JVM决定。d)用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。e)如果一个类实现了fin...

左耳听风的博客 357

(7):避免使用终结方法

finalize()方法一般来说是不可预测的,也是很危险的,一般情况下是不必要的。终结方法的缺点在于不能保证被及时的执行,甚至不会执行。finalize的工作原理是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.而程序员无法

ahui2333的博客 311

《EffectiveJava》读后感(第2章创建和销毁对象 第7条)

尽量避免使用终结方法 终结方法通常是不可测的,也是很危险的,一般情况下是不必要的。使用终结方法会导致行为的不稳定,降低性能,以及不可移植性。当然,终结方法也有其可取之处,但根据经验应该避免使用终结方法,这也是公司考试时很容易考到的选择题。 尽量比哦面使用Finalizer方法,因为低优先级易导致出现OOM的问题。另:创建和销毁对象会造成多余的性能消耗(约430倍)。应使用try-catah-finally显示总结,高效且一定执行。 可以使用Finalizer作为安全网,或者终止非关键资源,否则不要使用。如果

weixin_44029138的博客 138

Java创建和销毁对象的一些技巧和注意事项

总括 1.使用静态工厂方法代替构造方法 2.当构造函数有很多参数时考虑使用构建器 3.用私有构造器或枚举类型实现单例模式 4.在想让一个工具类不被实例化的时候使用私有构造函数 5.优先考虑使用依赖注入来引用资源 6.避免创建不必要的对象 7.消除不必要的对象引用 8.避免使用finalize和clear方法 9.try-with-resources优先于try-finally 1.使用静态工厂方法代替构造方法 如将boolean转成Boolean对象的方法: public static Boolean va

Cobb141的博客 1197
上一篇: Ubuntu apt-get彻底卸载软件包
下一篇: 8. 【对于所有对象都通用的方法】如何正确覆写equals方法
享学IT
博客等级 码龄12年 1516粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值