构造函数NotePanel(itemClass)引用缺少的类型itemClassI具有类NotePanel<T extends AbstractNoteItem> extends JPanel
,并且在单独的类中返回应该在方法期间创建的NotePanel
的方法:
public class NoteList extends JList {
...
public class NoteListModel extends AbstractListModel {
...
public NotePanel getPanelFromIndex(int index) {
if (!indexExists(index)) {
// FYI, indexExists(int) works fine
return null;
} else {
AbstractNoteItem item = getElementAt(index);
// FYI, getElementAt(int) works fine
assert (item != null);
Class<?> itemClass = item.getClass();
return (new NotePanel<itemClass> (item));
}
}
}
}
返回新NotePanel
的行上有一个错误:“构造函数NotePanel(itemClass)引用缺少的类型itemClass。”有人可以告诉我如何使这项工作?
如果这个代码不够,我很乐意提供更多代码。我的所有进口都是有序的(谢谢,组织进口!)。我没有看到任何明显的问题,但我也是使用泛型的新手。
提前致谢!
答案 0 :(得分:4)
您尝试做的事情不起作用,因为泛型类型参数仅在编译时存在;由于类型擦除,它们在运行时没有任何影响。因此,将在运行时获得的Class<?>
用作泛型类型参数是没有意义的。
如果你不想知道为什么NotePanel
首先是通用的,那就很难建议一个合适的选择。
答案 1 :(得分:1)
您只能使用常量通用参数。在这里,可以像AbstractNoteItem一样紧,但不能更窄。
可能,做
new NotePanel<AbstractNoteItem> (item)
会没事,你想要什么,但没有看到全局,很难说肯定。
此外,您的返回类型是普通的NotePanel,因此参数化其构造并不重要;无论你将它归还给谁都不会看到参数化。
正如另一个答案中所提到的,关键是Java Generics仅在编译时。它们不像生成不同代码的C ++模板,它只是一种更奇特的编译时类型检查形式。
答案 2 :(得分:0)
以下可能有效,也可能无效。这是关于generic methods的教程。
public class NoteList extends JList {
...
public class NoteListModel extends AbstractListModel {
...
public < T extends AbstractNoteItem > NotePanel < T > getPanelFromIndex(int index) {
if (!indexExists(index)) {
// FYI, indexExists(int) works fine
return null;
} else {
T item = ( T ) ( getElementAt(index) ) ; // this should generate a warning
// FYI, getElementAt(int) works fine
assert (item != null);
// not needed // Class<?> itemClass = item.getClass();
return (new NotePanel<T> (item));
}
}
} }
调用方法
class NoteItemImpl extends AbstractNoteItem { ... stuff ... }
Notelist notelist ;
// implicit type argument specification
NotePanel < AbstractNoteItem > n1 = notelist . getPanelFromIndex ( 1 ) ;
NotePanel < NoteItemImpl > n2 = notelist . getPanelFromIndex (2 ) ; // may generate class cast exception
// explicit type argument specification
NotePanel < AbstractNoteItem > n3 = notelist . < AbstractNoteItem > getPanelFromIndex ( 3 ) ;
NotePanel < NoteItemImpl > n4 = notelist . < NoteItemImpl > getPanelFromIndex ( 4 ) ; // may generate class cast exception
答案 3 :(得分:0)
如果我正确理解了这个问题,那么你有一个NotePanel
类,它有一个音符项成员。此注释项是AbstractNoteItem
的子类。但是您不希望将注释项指定为AbstractNoteItem
类型,因为您希望直接访问子类方法。
现在,如果所有这些子类方法具有相同的名称和相同的签名(跨层次结构),那么您根本不需要泛型;普通的旧多态将适合你。
但是如果子类方法完全不同,那么你想要的是单独的NotePanel
类,每种类型的注释项都有一个。在您的问题中,您似乎想要使用泛型生成它们。由于擦除,这在Java中实际上是不可能的。正如另一个答案所提到的,C ++泛型将创建多个类,但是你不能用Java来实现它。
但是如果这些单独的NotePanel
类都有方法在每个AbstractNoteItem
子句中调用了不同的方法,那么我认为你真的需要编写单独的NotePanel
子类!如果需要,这种并行的类层次结构并不是那么糟糕。
如果您选择此路线,请使用工厂方法替换对NoteItem
构造函数(您无法工作的构造函数)的调用,以创建正确类型{{ 1}}子类。