集合变成了原始类型

6
例如,我们有一些抽象类(AbsractClass)。
package inherit;

import java.util.HashSet;
import java.util.Set;

/**
 * TODO: Add comment
 *
 * @author Ruslan Ibragimov
 */
public abstract class AbstractClass<T extends Integer> {

    private Set<String> strings = new HashSet<>();

    private T value;

    public Set<String> getStrings() {
        return strings;
    }

    public void setStrings(Set<String> strings) {
        this.strings = strings;
    }

    public void addString(String string) {
        strings.add(string);
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }
}

还有一些子节点:

package inherit;

/**
 * TODO: Add comment
 *
 * @author Ruslan Ibragimov
 */
public class InheritClass extends AbstractClass<Integer> {


}

让我们进行简单测试。
package inherit;

/**
 * TODO: Add comment
 *
 * @author Ruslan Ibragimov
 */
public class TestClass {

    public static void main(String[] args) {
        TestClass testClass = new TestClass();
        testClass.test(new InheritClass());
    }

    private AbstractClass test(AbstractClass aClass) {
        for (String string : aClass.getStrings()) {
            System.out.println(string);
        }
        return aClass;
    }
}


Make output:

Error:(16, 51) java: incompatible types
required: java.lang.String
found:    java.lang.Object
for (String string : aClass.getStrings()) {

为什么会发生这种情况?

我不这么认为,因为“getStrings()”返回“Set<String>”。 - bsmk
我敢打赌,如果你使用无界通配符声明 AbstractClass<?>,那么你的代码很可能会编译通过。 - Meno Hochschild
@Joe,不是我明确指定了类型吗:“private Set<String> strings = …” - Ruslan
@MenoHochschild,没错,我知道,但是为什么我需要这样做呢? - Ruslan
5
原文:The raw type erases not only the generic parameter but also all other generic types so that Set<String> becomes Set. It is explained here: Why won't this generic java code compile?翻译:原始类型不仅擦除了泛型参数,还会将所有其他泛型类型都擦除,因此Set<String>会变成Set。这在此处有解释:为什么这个泛型Java代码不能编译? - Radiodef
显示剩余5条评论
1个回答

0

相反:

private AbstractClass test(AbstractClass aClass) {

使用

private AbstractClass test(AbstractClass<? extends Integer> aClass) {

这将修复编译器,如果您在代码辅助中检查getStrings()的返回值,则会看到Set的意图。也可以阅读Radiodef在评论中提供的链接。


AbstractClass<?> 更好,但这不是问题的本质。 - Ruslan
@IRus,我认为你需要修复那个问题,这就是为什么我回答的原因。 - Lukino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接