[英]Generic parameter as variable - Java
构造函数NotePanel(itemClass)引用缺少的类型itemClass我有一个类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)引用缺少的typeItemClass。” 有人可以告诉我如何进行这项工作吗?
如果这还不够,我将很乐意提供更多代码。 我所有的进口货物都已整理好(谢谢您,整理进口货物!)。 我看不到任何明显的问题,但是使用泛型也是新手。
提前致谢!
您尝试执行的操作无法正常工作,因为泛型类型参数仅在编译时存在。 由于类型擦除,它们在运行时没有影响。 因此,将在运行时获得的Class<?>
用作通用类型参数是没有意义的。
在不知道为什么首先要使NotePanel
通用的情况下,很难提出适当的替代方案。
您只能使用常量通用参数。 在这里,它可以像AbstractNoteItem一样紧密,但不会更窄。
大概在做
new NotePanel<AbstractNoteItem> (item)
可以,您想要什么,但是没有看到全局,很难确定。
同样,您的返回类型是普通的NotePanel,因此参数化其构造并不重要。 无论您将它退还给谁,都不会看到参数化。
如另一个答案中所述,关键是Java泛型仅在编译时。 它们与生成不同代码的C ++模板不同,它只是编译时类型检查的一种更奇特的形式。
以下内容可能有效也可能无效。 这是有关泛型方法的教程。
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
如果我正确理解了此问题,则说明您有一个具有注释项成员的NotePanel
类。 此注释项是AbstractNoteItem
的子类。 但是,您不想为注释项指定AbstractNoteItem
类型,因为您希望直接访问子类方法。
现在,如果所有这些子类方法都具有相同的名称和相同的签名(在整个层次结构中),那么您根本就不需要泛型。 普通的老式多态性将为您工作。
但是,如果子类方法完全不同,则您需要的是单独的NotePanel
类,每种注释项类型一个。 在您的问题中,您似乎想使用泛型来生成它们。 由于擦除,这在Java中实际上是不可能的。 如另一个答案中所述,C ++泛型将创建多个类,但是您不会在Java中得到它。
但是,如果这些单独的NotePanel
类在每个AbstractNoteItem
子类中都具有调用不同方法的方法,那么我认为您真的需要编写单独的NotePanel
子类! 如果需要,这种并行的类层次结构并没有那么糟糕。
如果走这条路,那么用创建正确类型的NoteItem
子类的工厂方法替换对NoteItem
构造函数的调用(您无法使用的调用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.