Java中的数组有"finalize"方法吗?

Is there a "finalize" method for arrays in Java?

假设在java中,我想在数组(例如int[] a = new int[3])被垃圾回收时做一些操作。我知道对象有一个 finalize 方法。但是数组有“finalize”方法吗?

整个终结器都已过时。

ReferenceQueue系统取代它,可以做到这一点。

但请注意,垃圾回收通常根本不会发生。 VM 将在内存用完之前关闭。无法保证不再可访问的数组会在几分钟内被删除。这可能需要几天时间。或者它真的只需要片刻。你得不到保证。

如果您可以使用 java-9 及更高版本,则可以使用 cleaner API。您需要仔细阅读文档,以免(以及 apiNote)您不会踩到明显的错误:

The cleaning action is invoked only after the associated object becomes phantom reachable, so it is important that the object implementing the cleaning action does not hold references to the object

您还需要在 array 周围创建一个包装器,但除此之外它是非常可行的。这是一个模拟的例子:

    public static void main(String[] args) {

        ArrayWrapper wrapper = new ArrayWrapper(new int[]{1,2,3});
        wrapper = null;
        gc();

        System.out.println("Done");

    }

    static void gc() {
        for(int i=0;i<3;++i){
            LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100));
            System.gc();
        }
    }

    static class ArrayWrapper implements AutoCloseable {

        private static final Cleaner CLEANER = Cleaner.create();
        private final Inner inner;
        private final Cleaner.Cleanable cleanable;

        public ArrayWrapper(int[] array) {
            this.inner = new Inner(array);
            cleanable = CLEANER.register(this, inner);
        }

        public int[] getArray() {
            return inner.array;
        }

        @Override
        public void close() {
            System.out.println("close called");
            cleanable.clean();
        }

        static class Inner implements Runnable {

            private final int [] array;

            public Inner(int[] array) {
                this.array = array;
            }

            @Override
            public void run() {
                System.out.println("Run called");
            }
        }
    }

当运行这个时,我得到:

Run called
Done

这基本上告诉您,一旦 wrapper 被垃圾收集,它就会在 Inner 中运行操作(即 Runnable)。

请注意 ArrayWrapper 还实现了 AutoCloseable,因此如果您的代码允许,您可以在 try with resource 构造中使用它。那也会简单得多;如果您想实现类似:“当包装器超出范围时,在关闭方法中执行一些操作”。