三元条件运算符中的不兼容类型

时间:2015-10-24 20:09:03

标签: java generics java-7 conditional-operator

我正在尝试根据特定条件为下拉框设置自定义渲染器:

themeComboBox.setRenderer(
    settings == null ? themeComboBox.getRenderer() : new ThemeNameRenderer());

其中themeComboBoxjavax.swing.JComboBox<Path>的实例,ThemeNameRenderer是扩展DefaultListCellRenderer的自定义类。

这不会编译,出现以下错误

method setRenderer in class JComboBox<E> cannot be applied to given types;
    themeComboBox.setRenderer(settings == null ? themeComboBox.getRenderer() : new ThemeNameRenderer());
  required: ListCellRenderer<? super Path>
  found: ListCellRenderer<CAP#1>
  reason: actual argument ListCellRenderer<CAP#1> cannot be converted to ListCellRenderer<? super Path> by method invocation conversion
  where E is a type-variable:
    E extends Object declared in class JComboBox
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ? extends Object

如何使用条件运算符实现此功能?

  • 我无法使用if语句或类似语句对setRenderer的调用进行包围,因为我通过NetBeans GUI编辑器自定义代码。事实上,我需要做的全部原因是ThemeNameRenderer使用在编辑器中设计GUI时不应加载的依赖项。

  • 我的目标是Java 1.7。我认为代码在Java 1.8上编译。

  • 我发现以下代码确实有效,但我想尽可能避免使用额外的方法。

    themeComboBox.setRenderer(pickRenderer());
    
    private ListCellRenderer<? super Path> pickRenderer() {
        if (settings == null) {
            return themeComboBox.getRenderer();
        } else {
            return new ThemeNameRenderer();
        }
    }
    

1 个答案:

答案 0 :(得分:0)

似乎他们在Java 8中对类型推断添加了一些改进,这可能解释了行为的差异。

检查此页面中的“目标类型”部分:

https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

  

什么是目标类型的概念已经扩展到包括方法参数

这段代码很适合我使用Java 1.7(需要添加一个强制转换):

themeComboBox.setRenderer(
            (ListCellRenderer<? super Path>) (settings == null ? themeComboBox.getRenderer() : new ThemeNameRenderer()));

使用Java 1.8编译原始代码:

themeComboBox.setRenderer(
            settings == null ? themeComboBox.getRenderer() : new ThemeNameRenderer());