Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中清理对象的最佳方法是什么? 我们在java中没有任何析构函数,就像C++中的。p>_Java - Fatal编程技术网

在Java中清理对象的最佳方法是什么? 我们在java中没有任何析构函数,就像C++中的。p>

在Java中清理对象的最佳方法是什么? 我们在java中没有任何析构函数,就像C++中的。p>,java,Java,Q1.我们应该如何清理java中的任何对象 第二季度。是否有最终块的替代方案 Q3.有时我们必须从类中明确调用第三方代码的初始化/终止,例如 public classs MyClass{ public MyClass(){ ThirdPartyInitialize(); } protected void finalize(){ ThirdPartyTerminate(); } } 这是正确的方法吗?finalize的使用方式类似

Q1.我们应该如何清理java中的任何对象

第二季度。是否有最终块的替代方案

Q3.有时我们必须从类中明确调用第三方代码的初始化/终止,例如

public classs MyClass{
    public MyClass(){
        ThirdPartyInitialize();
    }

    protected void finalize(){
        ThirdPartyTerminate();
    }
}

这是正确的方法吗?

finalize的使用方式类似于析构函数,但是,如果您对资源使用try…finally块,则可以打开资源,并在finally块中关闭资源

当块退出时,总是调用finally块,无论是正常还是通过抛出异常

Finalize对于资源管理来说是有风险的,因为您不知道何时会调用它,如果它关闭一个也有Finalize的对象,那么可能需要一段时间

最后一个块是更好的方法。

如果您的程序也正在关闭,您也可以在程序中添加一个:

//add shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        ThirdPartyTerminate();
    }
});

清理对象后的最佳方法是直接放下对象

最后,可以使用executearound习惯用法抽象块

应避免进入决赛。他们可能不会马上接到电话。无论如何,清理工作应该进行。它们相对较慢。如果您正在编写低级别的资源包装器(例如,文件句柄),如果性能不重要,您可能需要添加一个作为安全网。

关于终结器的一个很好的见解。

您通常无法自己“清理”Java对象。垃圾收集器决定何时清理对象。您可以通过将对象引用设置为
null
来指示何时完成对象引用,但一般来说,让它超出范围就足够了。不管怎样,您仍然无法控制它何时被回收垃圾

finally
块用于执行操作,无论是否从
try
块引发异常,并且是执行清理的最佳位置。通常,您只需要清理非对象资源,如开放流

finalize()
不能保证被调用,因为不能保证在程序退出之前调用垃圾收集器。它实际上不是一个C++析构函数,因为C++析构函数总是被调用,并且可以依赖它们调用。您不能依赖调用
finalize()


因此,1)使用
最后
块释放非对象资源2)让垃圾收集器清理对象资源3)如果在长期运行的方法中使用某个对象,可以通过将其设置为
null
来提示垃圾收集器您已处理完该对象。

您可以通过删除对该对象的引用来清理对象,当你不再需要它的时候。你不必明确地这样做。显式清理需要将引用设置为null,从而向垃圾收集器提供可以收集对象的提示。此提示之所以有效,是因为每个对象的内部引用计数都是在内部维护的。 比如说


C a = new C(); //create an object of class C and assign it to 'a'
a = new C(); //create another object of class C and assign it to 'a'. The older object is no longer referred to. It is now eligible for GC.
finalize()有更好的替代方法,这取决于finalize()对您的情况有多大帮助

通常,最佳实践是在API中提供类似close()或disposeResources()的方法,这将允许调用方帮助API清理自身。比如,。这比finalize()方法要好,因为JVM将调用finalize()方法。finalize()方法通常由JVM中的低优先级线程运行,从而导致某些奇怪的错误

在连接类的情况下,在许多应用程序中,等待JVM执行终结的代价确实很高,因为一个数据库一次只能接受这么多的连接。因此,大多数程序员都会显式地对连接对象调用close()

在您的情况下,它应该转换为类似的内容(在这种情况下,finally块保证始终运行)


这类似于连接类在大多数情况下的使用方式。

Java中的对象真的不需要“清理”,GC就可以工作。几乎每次我在代码中看到someObject=null时,总是有人不知道自己在做什么。这有一个理论上的例子,但它实际上是一个边缘案例,通常用其他方式处理会更好,比如最近添加的try-with-resource

如果有一个外部资源需要在对象不再使用时清理,那就另当别论了

有一些“引用”类将持有对类的特殊类型的引用——它不会停止垃圾收集,但可以在类被垃圾收集时通知您(如果您愿意,可以通过回调)。查找WeakReference、PhantomReference等


与实际的“finalize”方法相比,这些方法是可靠的,并且工作方式更加确定,因为回调在类之外,因此您不会在某些预删除或半删除状态下执行方法,也不会出现可能导致的问题。

两个语法选项:

1)龙目岛中有一种注释,大多类似于C++析构函数():

2) 还有一项声明。例如:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
}

您可以在Java 9中使用,

我不会说finalize()类似于析构函数。你的文章的其余部分很好,但它在很大程度上与第一句话相矛盾。您永远不知道何时将调用finalize()。所以它不同于一个C++析构函数,它在对象离开范围或被删除时被调用。当对象是垃圾收集时,将调用终结器,但不知道它何时被垃圾收集,因此终结器可能不会及时调用。我不确定你的意思。如果您不立即释放资源,那么您就有潜在的问题(不仅仅是性能问题)。如果您没有抛出异常,那么在任何合理的异常实现上,它与
@Cleanup
ResourceClass resource = new ResourceClass();
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
}