Java 了解TaskListener的泛型类型参数

Java 了解TaskListener的泛型类型参数,java,generics,swing-app-framework,jsr296,Java,Generics,Swing App Framework,Jsr296,我目前正在重构一些旧代码,发现了一个片段,我不知道如何正确使用Swing应用程序框架类的泛型TaskListener.Adapter 这是相关的代码片段: public void executeTask(Task<?, ?> task, boolean handleException) { task.addTaskListener(new TaskListener.Adapter() { /* <-- Two warnings here */ @Over

我目前正在重构一些旧代码,发现了一个片段,我不知道如何正确使用Swing应用程序框架类的泛型
TaskListener.Adapter

这是相关的代码片段:

public void executeTask(Task<?, ?> task, boolean handleException) {
    task.addTaskListener(new TaskListener.Adapter() { /* <-- Two warnings here */
        @Override
        public void failed(TaskEvent event) { /* ... */ }
    });
    getContext().getTaskService().execute(task);
}
我得到“方法不重写超类型中的方法”。我必须再次使用原始
任务事件
。为什么呢

谢谢你的帮助

编辑:上TaskListener的Javadoc

  • 您是否尝试过新建TaskListener.Adapter
  • 当您尝试添加
    类型参数时,您的
    新TaskListener.Adapter
    是作为原始类型创建的,还是具有泛型类型参数

    在第一种情况下,编译器将整个类(及其超类)视为原始类型(为了向后兼容)。也就是说,类中的所有泛型类型参数,不管它们是类特定的还是方法特定的,都将被忽略。因此,当它找到带有泛型参数的方法声明时,它将与带有原始参数的超类方法进行比较。因此,没有对手


  • 由于不知道库和源代码,我猜:

    public <K, V> void executeTask(final Task<K, V> task, boolean handleException) {
        task.addTaskListener(new TaskListener.Adapter<K, V>() {
            @Override
            public void failed(final TaskEvent<Throwable> event) {
                super.failed(event);
            }
        });
        getContext().getTaskService().execute(task);
    }
    
    public void executeTask(最终任务任务,布尔handleException){
    task.addTaskListener(新的TaskListener.Adapter(){
    @凌驾
    公共作废失败(最终TaskEvent事件){
    超级。失败(事件);
    }
    });
    getContext().getTaskService().execute(任务);
    }
    

    (编辑:我下载了lib,上面的代码在没有警告的情况下编译)

    您不能将泛型为
    的适配器应用于
    任务,因为谁知道通配符是什么?它可能是一个
    任务
    ,在这种情况下,适配器的边界不匹配,因此不适用


    (好的,在这种情况下,可能是因为它们是消费者,所以它们是可以的,但是编译器本身无法推断。如果是这种情况,那么需要声明
    Task.addtasklister
    以获取
    TaskListener您可以发布
    TaskListener.Adapter
    的声明,特别是它的泛型参数吗?我添加了一个link到类的Javadocs。(这是一个标准的Swing应用程序框架类。)新的TaskListener。适配器无法工作。编译器无法知道这些问号是否与外部问号匹配。1.是的,但只是出于绝望:)。它无法工作(请参阅@Seans注释)2.TaskListener.Adapter有泛型参数,但该特定方法不使用它们,它显式地使用了
    Throwable
    @DR,在我上面描述的情况下,编译器会丢弃类中的所有泛型类型参数,而不管这些参数是特定于类的还是特定于方法的。@Sean,我觉得OP不能更改
    executeTask
    的签名。如果他可以,当然最好按照你和Andrzej描述的方式来做。@Péter Török:如果OP不能更改签名(它在哪里说?),然后他可以创建一个包装器方法,它接受
    ,然后将它传递给一个用
    声明的私有方法,就像其他人所说的那样。将泛型参数添加到我的方法中可以让我使用
    。奇怪的是……我看不出这两件事是如何关联的。@DR me;也许编译器会对原始代码抛出一个stroppe决定在整个类中忽略泛型边界。这很可能是Sun的
    javac
    中的一个bug,我遇到了一些与泛型相关的bug,特别是在处理更“有趣”的情况时。@DR,原因正是我在下面的回答中试图解释的。
    public <K, V> void executeTask(final Task<K, V> task, boolean handleException) {
        task.addTaskListener(new TaskListener.Adapter<K, V>() {
            @Override
            public void failed(final TaskEvent<Throwable> event) {
                super.failed(event);
            }
        });
        getContext().getTaskService().execute(task);
    }
    
    public <T, V> void executeTask(Task<T, V> task, boolean handleException) {
        task.addTaskListener(new TaskListener.Adapter<T, V>() {
            @Override
            public void failed(TaskEvent event) { /* ... */ }
        });
        getContext().getTaskService().execute(task);
    }