Java Generic:为什么编译器无法将类型T解析为方法中的继承类型?

时间:2015-04-09 11:04:39

标签: java generics

我有课程

public class DiaryItem extends AbstractInfoElement { ... };

public class EventItem extends AbstractInfoElement { ... };

public class StickerItem extends AbstractInfoElement { ... };

public class TodoItem extends AbstractInfoElement { ... };

我已经覆盖了使用此参数执行某些操作的方法:

class DBEngine {

    public long add(EventItem item){ ... };

    public long add(StickerItem item){ ... };

    public long add(TodoItem item){ ... }

}

然后我意识到模板类以通用方式操作类型

public class AddItemCommand<T extends AbstractInfoElement>{

    private final T item;

    public AddItemCommand(T item) {
        this.item = item;
    }

    void doSmth() {
      add(item);
    }
}

我想编译器会根据需要解析T,但是我遇到了问题:

Error:(78, 45) error: no suitable method found for add(T)
method DBEngine.add(DiaryItem) is not applicable
(argument mismatch; T cannot be converted to DiaryItem)
method DBEngine.add(EventItem) is not applicable
(argument mismatch; T cannot be converted to EventItem)
method DBEngine.add(StickerItem) is not applicable
(argument mismatch; T cannot be converted to StickerItem)
method DBEngine.add(TodoItem) is not applicable
(argument mismatch; T cannot be converted to TodoItem)
where T is a type-variable:
T extends AbstractInfoElement declared in class AddItemCommand

我的目标是在这些情况下避免过度编码:

AddItemCommand<DiaryItem> cmdDiary = new AddItemCommand<DiaryItem>(new DiaryItem);
cmdDiary.doSmth();

应致电

DBEngine.add(DiaryItem item);

AddItemCommand<TodoItem> cmdTodo = new AddItemCommand<TodoItem>(new TodoItem);
cmdTodo.doSmth();

应致电

DBEngine.add(TodoItem item);

这一切,但不起作用......这些问题是在编译时...

BTW ...请原谅我可怜的英语

1 个答案:

答案 0 :(得分:3)

从您的错误消息中可以看出,您只有add个具体子类的方法,DiaryItemEventItemStickerItemTodoItem,但然后你尝试 使用类型为T extends AbstractInfoElement的参数调用add。

这不起作用T(&#34; AbstractInfoElement的任何子类&#34;)与任何特定的子类都不匹配。

编辑:请注意,Java仅对静态类型进行调度(即,根据编译时已知的类型选择要调用的重载方法),因此无法进行知道T是否匹配其中一个子类。

(例如,How does Java method dispatch work with Generics and abstract classes?Java Generic / Type Dispatch QuestionMethod overloading and generics