【问题标题】:Java generics not applicable for the arguments issueJava 泛型不适用于参数问题
【发布时间】:2016-03-19 17:47:28
【问题描述】:

我正在编写的通用框架存在问题。 有人可以向我解释一下,为什么我的代码无法编译?我试图用这个简单的例子来展示它。 (更新示例)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

public class TestGeneric {

    public static void main(String... sss) throws Exception {

        Dao dao = new Dao("Hello");
        dao.extend();

        System.out.println(dao.getHelloWorld());
    }
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation {

    public Class<? extends AbstractCommand<? extends AbstractDao>>[] commands() default {};
}

abstract class AbstractDao {

    public void extend() throws Exception {

        for (Field field : this.getClass().getDeclaredFields()) {

            if (field.isAnnotationPresent(TestAnnotation.class)) {

                TestAnnotation annotation = field.getAnnotation(TestAnnotation.class);

                for (Class<? extends AbstractCommand<? extends AbstractDao>> commandClass : annotation.commands()) {

                    AbstractCommand<? extends AbstractDao> command = commandClass.newInstance();
                    command.doSomething(this);
                }
            }
        }
    }
}

class Dao extends AbstractDao {

    @TestAnnotation(commands = { Command.class })
    private String hello;

    private String world;

    public Dao(String hello) {
        this.hello = hello;
    }

    public String getHello() {
        return this.hello;
    }

    public void setWorld(String world) {
        this.world = world;
    }

    public String getHelloWorld() {
        return this.hello + " " + this.world;
    }
}

abstract class AbstractCommand<T extends AbstractDao> {
    public abstract void doSomething(T t);
}

class Command extends AbstractCommand<Dao> {

    @Override
    public void doSomething(Dao t) {

        if (t.getHello().equals("Hello")) {
            t.setWorld("World");
        }
    }
}

只要我做出以下更改...

abstract class AbstractCommand<T extends AbstractDao> {
    public abstract void print(AbstractDao t);
}

class Command extends AbstractCommand<Dao> {

    @Override
    public void doSomething(AbstractDao t) {

        Dao dao = (Dao) t;

        if (dao.getHello().equals("Hello")) {
            dao.setWorld("World");
        }
    }
}

...一切正常,但我必须一直使用 AbstractDao。

据我所知,一切都应该保存,但我不断收到此错误。

AbstractCommand 类型中的方法 print(capture#3-of ? extends AbstractDao) 不适用于参数 (Dao)

但是 Dao 扩展了 AbstractDao,那么问题到底出在哪里?

我已经找到了这个问题generics error: not applicable for the arguments,但我不确定这是否与我遇到的问题相同。

我的猜测是它与'Because the Java compiler erases all type parameters in generic code, you cannot verify which parameterized type for a generic type is being used at runtime'有关

有人有解决这个问题的办法吗?

谢谢!

【问题讨论】:

  • 你想做什么? AbstractCommand&lt;? extends AbstractDao&gt; 表示它是扩展 AbstractDaosome 未知类型的 AbstractCommand。这可能是也可能不是Dao,编译器无法知道。
  • 可能重复 stackoverflow.com/q/2723397/2891664AbstractCommand 是消费者,而不是生产者。
  • 我已经更新了我的示例,使其更清楚,我试图实现的目标。 Dao 有什么方法不能扩展 AbstractDao 吗?

标签: java generics bounded-wildcard


【解决方案1】:

您正在使用AbstractCommand 引用。

试试这个

((Command)command).print(new Dao("Hello World"));

【讨论】:

  • 我不知道,它是 Command 实例还是在我调用该方法时扩展 AbstractCommand 的其他实例。
  • @BenGe89 在这种情况下,您知道它的命令,因为您使用的是Command.class
  • @BenGe89 尝试改写Command command = clazz.newInstance();。然后类型不匹配错误发生在那个时候,可能更有启发性。 知道它是Command,但clazz的静态类型是AbstractCommand,所以实例化需要向下转换。
  • “我不知道,在我调用该方法时,它是 Command 实例还是扩展 AbstractCommand 的其他实例。” 那你怎么知道你可以用Dao 拨打print 吗?如果是AbstractCommand&lt;SomeOtherDao&gt; 怎么办?
  • @Radiodef 我已经更新了示例。希望我的问题现在更清楚了。我不知道扩展 AbstractDao 的类,也不知道扩展 AbstractCommand 的类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 2023-03-18
  • 1970-01-01
  • 2016-11-17
相关资源
最近更新 更多