首页 > 解决方案 > 如何使用带有泛型的密封类?

问题描述

我有一个父抽象类和采用泛型的子类。

public abstract sealed class Parent<T> permits ChildA, ChildB {}

public non-sealed class ChildA<T extends FileTypeA> extends Parent{}

public non-sealed class ChildB<T extends FileTypeB> extends Parent{}

在父类中,我收到警告:

ChildA is a raw type. References to generic type ChildA<T> 
       should be parameterized

ChildB is a raw type. References to generic type ChildB<T> 
       should be parameterized

在子类中,我收到警告:

Parent is a raw type. References to generic type Parent<T> 
       should be parameterized

使它们像这样参数化:

public abstract sealed class Parent<T> 
    permits ChildA<T extends FileTypeA>, ChildB<T extends FileTypeB> {}

甚至

public abstract sealed class Parent<T> 
    permits ChildA<T>, ChildB<T> {}

给出错误:

Bound mismatch: The type T is not a valid substitute for the 
    bounded parameter <T extends FileTypeA> of the type ChildA<T>

如何删除这些警告和错误?

标签: javaeclipsejava-17java-sealed-type

解决方案


警告“<em>Parent is a raw type”与密封类完全无关,因为使用extends ParentwhenParent<T>是泛型类会导致这样的警告,因为泛型存在。

你很可能想要使用

public non-sealed class ChildA<T extends FileTypeA> extends Parent<T> {}

public non-sealed class ChildB<T extends FileTypeB> extends Parent<T> {}

另一个问题似乎是 Eclipse 错误,因为我只能在那里重现警告。当我将声明更改为 时permits ChildA<?>, ChildB<?>,警告消失,但您不应该这样做。

Java 语言规范permits子句定义为

ClassPermits:
    permits TypeName {, TypeName}

TypeName

TypeName:
    TypeIdentifier
    PackageOrTypeName . TypeIdentifier

PackageOrTypeName:
    Identifier
    PackageOrTypeName . Identifier

这显然会导致一系列点分隔标识符没有任何类型参数。始终如一javac地拒绝像permits ChildA<?>, ChildB<?>.

换句话说,Eclipse 不应在此处生成警告,更重要的是,不应在permit子句中接受参数化类型。您最好的选择是等待 Eclipse 的 Java 17 支持修复。@SuppressWarnings("rawtypes")您可以在整个班级中添加 a以Parent使警告消失,但是由于这会影响整个班级,因此我不建议这样做。


推荐阅读