为什么在 wicket 模型中调用 finalize 方法 2 次

Why is finalize method called 2 times in wicket model

在我的应用程序中,我有 class 扩展检票口模型并覆盖最终方法(只需删除异步生成的文件)。问题是在 wicket 页面第一次加载后立即调用最终方法,然后再次调用

public class TournamentFileReadOnlyModel<I> extends AbstractReadOnlyModel<File> {

    private static final long serialVersionUID = 1L;

    private CallableService callableService;
    private String uuid;

    public TournamentFileReadOnlyModel(CallableService callableService, I input,
            Class<? extends AbstractPdfCallable<I>> callableClass) {
        this.uuid = UUID.randomUUID().toString();
        this.callableService = callableService;
        callableService.createFile(uuid, WicketApplication.getFilesPath(), input, callableClass);
    }

    @Override
    public File getObject() {
        return callableService.getFile(uuid);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        callableService.finalizeFile(uuid);
    }
}

我用这个模型创建了 link:

    private void addPrintGroupButton() {
        add(new DownloadModelLink("printGroup", new TournamentFileReadOnlyModel<GroupPageDto>(callableService,
                groupPageDto, GroupPdfCallable.class)));
    }

日志:

  1. 时间被无缘无故地叫给我,因为我只是加载网页并且仍然有模型参考

    17:50:45.493 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Cleaning file from cache with uuid: 61286bf6-da4c-4905-b65d-d6061eb1466f

  2. 时间对我来说没问题,因为我加载了另一个网页并且已经丢失了该模型的参考

    17:51:10.913 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Error when cleaning file from cache with uuid: 61286bf6-da4c-4905-b65d-d6061eb1466f java.lang.NullPointerException at org.tahom.processor.service.callable.CallableService.finalizeFile(CallableService.java:65) [tahom-processor-0.2.0-SNAPSHOT.jar:?] at WICKET_org.tahom.processor.service.callable.CallableService$$FastClassByCGLIB$eb5c9b.invoke() [cglib-3.1.jar:?] at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [cglib-3.1.jar:?] at org.apache.wicket.proxy.LazyInitProxyFactory$AbstractCGLibInterceptor.intercept(LazyInitProxyFactory.java:350) [wicket-ioc-7.1.0.jar:7.1.0] at WICKET_org.tahom.processor.service.callable.CallableService$$EnhancerByCGLIB$212df1.finalizeFile() [cglib-3.1.jar:?] at org.tahom.web.model.TournamentFileReadOnlyModel.finalize(TournamentFileReadOnlyModel.java:33) [classes/:?] at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method) ~[?:1.7.0_25] at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101) [?:1.7.0_25] at java.lang.ref.Finalizer.access0(Finalizer.java:32) [?:1.7.0_25] at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190) [?:1.7.0_25]

更新

嗯,你是对的。还有另一个模型实例。但是后来我不知道不同模型如何共享相同的 uuid。但这是另一个问题

21:08:55.980 [qtp13530976-43] DEBUG org.tahom.processor.service.callable.CallableService - Creating file with uuidb485a4d1-ef67-4255-af64-4d7df6001b09 21:08:55.980 [qtp13530976-43] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - UUID b485a4d1-ef67-4255-af64-4d7df6001b09 generated for classorg.tahom.web.model.TournamentFileReadOnlyModel@1ba03be

21:08:56.794 [Finalizer] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - Class org.tahom.web.model.TournamentFileReadOnlyModel@14be425 21:08:56.907 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Cleaning file from cache with uuid: b485a4d1-ef67-4255-af64-4d7df6001b09

21:09:23.696 [Finalizer] WARN org.tahom.processor.service.callable.CallableService - Error when cleaning file from cache with uuid: b485a4d1-ef67-4255-af64-4d7df6001b09 21:09:23.696 [Finalizer] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - Class org.tahom.web.model.TournamentFileReadOnlyModel@1d76f52

很可能您正在处理(在代码的其他区域)TournamentFileReadOnlyModel.

的两个实例

许多框架创建和销毁实例而不是保存它们。有些人这样做是为了将一个实例与另一个实例隔离开来(例如 Web 服务隔离连接)其他人这样做是为了验证 classes 是否属于正确的继承链(例如 SWT 的服务接口),有些人这样做只是为了验证一个细节。

无论如何,将所需的逻辑放入 finalize 块是众所周知的 "really bad pattern",虽然您可能想找出 class 被构造两次的原因,但请考虑不要这样做使用终结块。

这可能意味着使用不同的方法来管理您提到的临时文件;但是,使用不同的方法,您可以明确详细说明策略,而不是希望 JVM(不保证这样做)遵循您的策略。