Java 泛型 - 类型必须来自 Class T "or" extend S
Java Generics - Type must be from Class T "or" extend S
我正在开发一个 ComboBox(更多的是为了上下文而不是实际意义),我想知道 Java 泛型中是否存在“或”运算符。现在,声明看起来像这样:
public class SComboBox<T extends ComboBoxItem> extends JPanel {
其中 ComboBoxItem
是我为可以在 ComboBox 中使用的项目创建的界面。但是,我也想接受 String
作为一种类型,这似乎是一项艰巨的任务,因为:
String
是 final class
所以没有人可以扩展它。
- 我不确定你是否可以输入类似“|”的内容(or) 运算符,或者直接指定可接受的 class。由于 是 一个“与”运算符 (
<T extends A & B>
),所以我认为也可以使用“或”(|)。
我的问题本质上是第 2 点。我可以在泛型中指定 class 我想接受 and/or 使用类似“|”的东西吗?如果没有,是否有任何解决方法或者我应该放弃使用泛型的想法?
泛型没有“或”运算符,原因很简单。
在开头说明类型的想法是允许您在 class.
的实现中使用该类型的 方法
当您使用“与”运算符 (extends A & B
) 时,您知道无论传递给您什么对象,您都可以访问 A
class 的任何方法以及任何 B
class 的方法。
但是如果是“或”会怎样呢?然后向您传递一个对象,该对象可以是 ComboBoxItem
允许您使用 ComboBoxItem
的方法,或者它只是一个字符串,这意味着您不能使用任何此类方法。在编译时,你不知道你传递的是哪个对象,所以给出类型没有意义。
“或”没有帮助。如果您没有使用该对象的任何方法,您也可以根本不使用 extends
。
这里真正的问题是您正在尝试做什么,它可以应用于字符串和组合框项目,但不适用于其他任何东西。闻起来像是设计问题。
简而言之,这是不可能的。 class 无法从两个接口之一继承,因为无法确定实际实现了哪个 class。
您可以像 JayC667 提到的那样实现一个字符串包装器,并让它实现您的 ComboBoxItem 接口。
我假设您无论如何都需要 ComboBoxItem 引入的一些特殊功能。
一些例子:
interface ComboBoxItem{
String getDisplayText();
default Color getBgColor(){
return Color.WHITE;
}
default Color getFgColor(){
return Color.BLACK;
}
default ImageIcon getIcon(){
return null;
}
default boolean useIcon(){
return false;
}
}
并且通过一个只接受字符串输入的简单实现。
public class StringCbItem implements ComboBoxItem {
private final String text;
StringCbItem (String text){
this.text = text;
}
@Override
String getDisplayText(){
return text;
}
}
对于 ComboBox,我可能只使用默认的 JComboBox。
您可以通过传递自定义 ListCellRenderer 实现来覆盖其显示和呈现行为。
public class MyRenderer extends JLabel implements ListCellRenderer<ComboBoxItem> {
public MyRenderer () {
setOpaque(true);
}
public Component getListCellRendererComponent(JList<?> list,
ComboBoxItem value,
int index,
boolean isSelected,
boolean cellHasFocus) {
setText(value.getDisplayText());
setBackground(value.getBgColor());
setForeground(value.getFgColor());
if(value.useIcon()){
setIcon(value.getIcon());
}
return this;
}
}
这只是如何操作的一些示例,仅作为起点!
您可以在这里进一步阅读:
How to Use Combo Boxes
Interface ListCellRenderer
我正在开发一个 ComboBox(更多的是为了上下文而不是实际意义),我想知道 Java 泛型中是否存在“或”运算符。现在,声明看起来像这样:
public class SComboBox<T extends ComboBoxItem> extends JPanel {
其中 ComboBoxItem
是我为可以在 ComboBox 中使用的项目创建的界面。但是,我也想接受 String
作为一种类型,这似乎是一项艰巨的任务,因为:
String
是final class
所以没有人可以扩展它。- 我不确定你是否可以输入类似“|”的内容(or) 运算符,或者直接指定可接受的 class。由于 是 一个“与”运算符 (
<T extends A & B>
),所以我认为也可以使用“或”(|)。
我的问题本质上是第 2 点。我可以在泛型中指定 class 我想接受 and/or 使用类似“|”的东西吗?如果没有,是否有任何解决方法或者我应该放弃使用泛型的想法?
泛型没有“或”运算符,原因很简单。
在开头说明类型的想法是允许您在 class.
的实现中使用该类型的 方法当您使用“与”运算符 (extends A & B
) 时,您知道无论传递给您什么对象,您都可以访问 A
class 的任何方法以及任何 B
class 的方法。
但是如果是“或”会怎样呢?然后向您传递一个对象,该对象可以是 ComboBoxItem
允许您使用 ComboBoxItem
的方法,或者它只是一个字符串,这意味着您不能使用任何此类方法。在编译时,你不知道你传递的是哪个对象,所以给出类型没有意义。
“或”没有帮助。如果您没有使用该对象的任何方法,您也可以根本不使用 extends
。
这里真正的问题是您正在尝试做什么,它可以应用于字符串和组合框项目,但不适用于其他任何东西。闻起来像是设计问题。
简而言之,这是不可能的。 class 无法从两个接口之一继承,因为无法确定实际实现了哪个 class。
您可以像 JayC667 提到的那样实现一个字符串包装器,并让它实现您的 ComboBoxItem 接口。 我假设您无论如何都需要 ComboBoxItem 引入的一些特殊功能。
一些例子:
interface ComboBoxItem{
String getDisplayText();
default Color getBgColor(){
return Color.WHITE;
}
default Color getFgColor(){
return Color.BLACK;
}
default ImageIcon getIcon(){
return null;
}
default boolean useIcon(){
return false;
}
}
并且通过一个只接受字符串输入的简单实现。
public class StringCbItem implements ComboBoxItem {
private final String text;
StringCbItem (String text){
this.text = text;
}
@Override
String getDisplayText(){
return text;
}
}
对于 ComboBox,我可能只使用默认的 JComboBox。 您可以通过传递自定义 ListCellRenderer 实现来覆盖其显示和呈现行为。
public class MyRenderer extends JLabel implements ListCellRenderer<ComboBoxItem> {
public MyRenderer () {
setOpaque(true);
}
public Component getListCellRendererComponent(JList<?> list,
ComboBoxItem value,
int index,
boolean isSelected,
boolean cellHasFocus) {
setText(value.getDisplayText());
setBackground(value.getBgColor());
setForeground(value.getFgColor());
if(value.useIcon()){
setIcon(value.getIcon());
}
return this;
}
}
这只是如何操作的一些示例,仅作为起点!
您可以在这里进一步阅读:
How to Use Combo Boxes
Interface ListCellRenderer