【问题标题】:How to address this warning? - Is a raw type. References to generic type should be parameterized如何解决这个警告? - 是原始类型。对泛型类型的引用应该被参数化
【发布时间】:2018-11-12 08:58:20
【问题描述】:

我在 JavaFX 中创建了一个自定义表格单元格pursuant to this answer,因此我可以为单元格文本的不同部分设置不同的字体样式。

我在两种不同类型的 TableView 上使用这个自定义表格单元:TableView<Track>TableView<Album>

TrackAlbum 都实现了接口 AlbumInfoSource

public interface AlbumInfoSource {
    public String getAlbumTitle();
    public String getFullAlbumTitle();
    public String getReleaseType();
    public String getDiscSubtitle();
    public Integer getDiscCount();
    public Integer getDiscNumber();

}

我的自定义 TableCell 是使用该 AlbumInfoSource 键入的,因此它可以为 TableView<Album>TableView<Track> 呈现单元格。

这是基本代码:

public class FormattedAlbumCell<T, S> extends TableCell <AlbumInfoSource, String> {

    private TextFlow flow;
    private Label albumName, albumType, albumDisc;

    public FormattedAlbumCell () {
        /* Do constructor stuff */
    }

    @Override
    protected void updateItem ( String text, boolean empty ) {
        super.updateItem ( text, empty );
        /* Do pretty rendering stuff */
    }
}

然后我将它应用到这样的列:

TableColumn<Album, String> albumColumn;
albumColumn = new TableColumn<Album, String>( "Album" );
albumColumn.setCellFactory( e -> new FormattedAlbumCell () );

效果很好,但我在最后一行收到警告,上面写着:

警告:FormattedAlbumCell 是原始类型。对泛型类型 FormattedAlbumCell 的引用应该被参数化

如果我更改我的 FormattedAlbumCell 类,使其扩展 TableCell &lt;Album, String&gt;,那么警告就会消失。但是我不能将 FormattedAlbumCell 用于TableView&lt;Track&gt;,我将不得不复制 FormattedAlbumCell 类使其扩展 TableCell,这对我来说似乎很愚蠢。

有没有办法在不创建两个单独的类的情况下直接获取这些参数?问题似乎来自于接口有问题的参数化东西。

【问题讨论】:

  • 你为什么有&lt;T, S&gt;
  • 没有它,我会在设置单元工厂的那一行上收到错误而不是警告——“类型不匹配:无法从 FormattedAlbumCell 转换为 TableCell”。
  • 有人在现已删除的评论中建议我将其设为“e -> new FormattedAlbumCell ()”。这会产生错误“FormattedAlbumCell 类型不是通用的;它不能用参数 进行参数化”。
  • @JoshuaD 但FormattedAlbumCell 显然 通用的,如果它具有您显示的声明。你指的是正确的类吗?
  • 我已经编辑了原始帖子以使其更加清晰。

标签: java


【解决方案1】:

您的FormattedAlbumCell 有两个泛型类型参数(&lt;T, S&gt;),从表面上看,它们是完全未使用的。删除它们。

class FormattedAlbumCell<T, S> extends TableCell<AlbumInfoSource, String>

变成

class FormattedAlbumCell extends TableCell<AlbumInfoSource, String>

你的下一个问题是generics are invariantTableCell&lt;AlbumInfoSource, String&gt; 不是 TableCell&lt;Album, String&gt;,反之亦然。

如果您需要能够在您的方法中创建TableColumn&lt;Album, String&gt;,那么您需要TableCell&lt;Album...,而不是TableCell&lt;AlbumInfoSource...。但是您也希望它适用于 AlbumInfoSource 的其他实现,因此更改单元格将不起作用。

这意味着您需要通过泛型引入另一个级别的间接性。

class FormattedAlbumCell<T extends AlbumInfoSource> extends TableCell<T, String>

这表示我们可以创建 FormattedAlbumCell 的不同通用版本,但受限于 TAlbumInfoSource 的更具体类型(即扩展或实现它)。

现在我们可以创建一个FormattedAlbumCell&lt;Track&gt;,这将是一个TableCell&lt;Track, String&gt;,或者我们可以创建一个FormattedAlbumCell&lt;Album&gt;,这将是一个TableCell&lt;Album, String&gt;

另见Oracle's generics tutorial

【讨论】:

  • 这会导致当前给出警告的行出现错误——“类型不匹配:无法从 FormattedAlbumCell 转换为 TableCell
  • 专辑实现了专辑信息源。 FormattedAlbumCell 被少数几个不同的 TableView 使用,它们都显示实现了 AlbumInfoSource 的类。困难似乎在于用参数对其进行排序。您对复制/粘贴的评论没有帮助。
  • 是的,这似乎是导致警告的原因。谢谢你。鉴于代码有效并且创建重复的类似乎不可取(请参阅澄清对我原始帖子的编辑)我该怎么办?只是压制警告并继续前进?重构并接受重复的代码?还有什么?
  • 我无法更改albumColumn——那么我还必须更改albumTable,在其他地方它需要一个完整的Album,而不仅仅是狭窄的AlbumInfoSource。如果我将FormattedAlbumCell 更改为TableCell&lt;Album, ...,我将不得不制作该类的重复版本TableCell&lt;Track, ...,这似乎是不可取的。
  • 甜蜜!做到了。我还必须将setCellFactory 更改为:e -&gt; new FormattedAlbumCell&lt;&gt;。你能编辑你对这个解决方案的答案吗?如果你愿意,为什么会这样?那我就可以接受了。谢谢!
猜你喜欢
  • 2016-12-22
  • 2012-08-06
  • 2013-06-01
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多