Java有析构函数吗?

Java有析构函数吗?,java,garbage-collection,destructor,Java,Garbage Collection,Destructor,Java有析构函数吗?我似乎找不到关于这个的任何文档。如果没有,我如何才能达到同样的效果 为了使我的问题更具体,我正在编写一个处理数据的应用程序,规范中说应该有一个“重置”按钮,将应用程序恢复到其最初的刚启动状态。但是,除非关闭应用程序或按下重置按钮,否则所有数据都必须是“实时”数据 作为一名C/C++程序员,我认为实现这一点很简单。(因此,我计划最后实现它。)我构建了我的程序,使所有“可重置”对象都在同一个类中,这样我就可以在按下重置按钮时销毁所有“活动”对象 我在想,如果我所做的只是取消对数

Java有析构函数吗?我似乎找不到关于这个的任何文档。如果没有,我如何才能达到同样的效果

为了使我的问题更具体,我正在编写一个处理数据的应用程序,规范中说应该有一个“重置”按钮,将应用程序恢复到其最初的刚启动状态。但是,除非关闭应用程序或按下重置按钮,否则所有数据都必须是“实时”数据

作为一名C/C++程序员,我认为实现这一点很简单。(因此,我计划最后实现它。)我构建了我的程序,使所有“可重置”对象都在同一个类中,这样我就可以在按下重置按钮时销毁所有“活动”对象

我在想,如果我所做的只是取消对数据的引用并等待垃圾收集器收集数据,那么如果我的用户重复输入数据并按下重置按钮,不会出现内存泄漏吗?我也在想,既然Java作为一种语言已经相当成熟,应该有一种方法来防止这种情况发生,或者优雅地解决它。

不,这是最接近的方法

但是,调用时(如果)不保证。
请参阅:

函数是析构函数

但是,通常不应该使用它,因为它是在GC之后调用的,而您无法知道何时会发生(如果有)

此外,需要多个GC来解除分配具有
finalize()
的对象


您应该尝试使用
try{…}finally{…}
语句清理代码中的逻辑位置

因为Java是一种垃圾收集语言,所以您无法预测对象何时(甚至是否)被销毁。因此,没有析构函数的直接等价物

有一个继承的方法称为
finalize
,但这完全是由垃圾收集器自行决定调用的。因此,对于需要显式整理的类,约定是定义一个close方法并仅使用finalize进行健全性检查(即,如果未调用close,则立即执行并记录错误)


最近出现了一些,因此如果需要,应该提供更多的深度…

与Java中的析构函数最接近的等价物是方法。与传统析构函数的最大区别在于,您无法确定何时调用它,因为这是垃圾收集器的责任。我强烈建议在使用它之前仔细阅读,因为文件句柄等的典型RAIA模式无法可靠地与finalize()配合使用。

不,这里没有析构函数。原因是所有Java对象都是堆分配和垃圾收集的。如果没有显式的释放(即C++的delete操作符),就没有实现真正析构函数的合理方法

Java确实支持终结器,但它们只是用来保护持有本机资源句柄(如套接字、文件句柄、窗口句柄等)的对象。当垃圾收集器在没有终结器的情况下收集对象时,它只是将内存区域标记为空闲,仅此而已。当对象有一个终结器时,它首先被复制到一个临时位置(记住,我们在这里进行垃圾收集),然后它进入一个等待终结的队列,然后终结器线程以非常低的优先级轮询队列并运行终结器

当应用程序退出时,JVM将停止,而不等待挂起的对象被最终确定,因此实际上无法保证您的最终确定程序会运行。

应该避免使用finalize()方法。它们不是一种可靠的资源清理机制,滥用它们可能会导致垃圾收集器出现问题

如果需要在对象中进行释放调用,比如释放资源,请使用显式方法调用。这种约定可以在现有API(例如)中看到,通常通过try/finally调用

Resource r = new Resource();
try {
    //work
} finally {
    r.dispose();
}
尝试使用已处置对象时应引发运行时异常(请参阅)


编辑:

我在想,如果我所做的只是 取消对数据的引用并等待 垃圾收集器来收集它们, 如果我的 用户反复输入数据和 按下重置按钮


通常,您所需要做的就是取消对对象的引用-至少,这是它应该工作的方式。如果您担心垃圾收集,请查看(或JVM版本的等效文档)。

也许您可以尝试一下。。。finally块以在使用对象的控制流中完成对象。当然,它不会自动发生,但是C++中也不会发生破坏。您经常会在finally块中看到资源的关闭。

我完全同意其他答案,即不要依赖finalize的执行

除了try-catch-finally块,您还可以使用(Java1.3中介绍的)在程序中执行最终清理

与析构函数不同的是,但是可以实现一个关闭钩子,其中注册了侦听器对象,可以调用清理方法(关闭持久数据库连接、删除文件锁等),这通常是在析构函数中完成的。 同样-这不是析构函数的替代品,但在某些情况下,您可以使用它来实现所需的功能


这样做的好处是解构行为与程序的其余部分松散耦合。

首先,请注意,由于Java是垃圾收集的,因此很少需要对对象销毁做任何事情。首先是因为您通常没有任何可供释放的托管资源,其次是因为您无法预测何时或是否会发生,所以不适合“在没有人使用我的对象时”需要发生的事情
 * Called by the browser or applet viewer to inform
 * this applet that it is being reclaimed and that it should destroy
 * any resources that it has allocated. The stop() method
 * will always be called before destroy().
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
} catch (Exception e) {
  ...
} finally {
  ...
}
public class Closeable implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("closing..."); 
    }
    public static void main(String[] args) {
        try (Closeable c = new Closeable()) {
            System.out.println("trying..."); 
            throw new Exception("throwing..."); 
        }
        catch (Exception e) {
            System.out.println("catching..."); 
        }
        finally {
            System.out.println("finalizing..."); 
        } 
    }
}
public myDestructor() {

variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL

}
public void addShutdownHook(Thread hook)
accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );
@Cleanup
ResourceClass resource = new ResourceClass();
@Cleanup("dispose")
ResourceClass resource = new ResourceClass();