繁体   English   中英

泛型,继承和类型擦除问题

[英]Generics, Inheritance and Type Erasure problem

我不能全神贯注,为什么下面的代码片段(包括泛型和通配符)无效。

package test;

public class App {

    private interface Condition {
        String get();
    }

    private interface Processor<T extends Condition> {
        boolean process(final T condition);
    }

    private static class HolderClass<T extends Condition> {

        private final Processor<T> processor;
        private final T condition;

        public HolderClass(final Processor<T> processor, final T condition) {
            this.processor = processor;
            this.condition = condition;
        }

        public Processor<T> getProcessor() {
            return processor;
        }

        public T getCondition() {
            return condition;
        }

    }

    private static class FirstCondition implements Condition {
        @Override
        public String get() {
            return "concrete";
        }
    }

    private static class FirstProcessor implements Processor<FirstCondition> {
        @Override
        public boolean process(FirstCondition condition) {
            System.out.println(condition.get());
            return false;
        }
    }

    public static void main(String[] args) {
        final HolderClass<? extends Condition> holder = new HolderClass<>(new FirstProcessor(), new FirstCondition());
        holder.getProcessor().process(holder.getCondition()); // error here
    }

}

这会因Compilation failure .../test/App.java:[58,46] incompatible types: test.App.Condition cannot be converted to capture#1 of ? extends test.App.Condition Compilation failure .../test/App.java:[58,46] incompatible types: test.App.Condition cannot be converted to capture#1 of ? extends test.App.Condition

我已经阅读了很多有关类型擦除的信息,但是任何人都可以尝试解释实际的问题是什么,也许可以提供一个反例,说明为什么不允许这样做?

谢谢。

? extends 用来声明泛型类的? extends是经典的。 您可以使用它来设置泛型类的边界。
但是,在实例化泛型类型时,通常会指定需要处理的类型,并且不使用它仍然使用上限通配符来声明它,因为这会设置一些规则,从而为您提供一些可能性(从子类型变量赋值),但是还有些约束。

一个应该可以帮助您理解的示例:

List<? extends Number> numbers = null;
numbers.add(1); // Doesn't compile for same reason

如果要添加数字,请声明:

List<Number> numbers = null;
numbers.add(1);

通常,变量Foo<? extends Bar> 出于类型安全的原因,不能使用通用参数调用Foo<? extends Bar>

List<? extends Number> numbers = null;
List<? extends Float> floats = null;
numbers = floats;  // valid
numbers.add(Long.valueOf(1)); // doesn't compile since no type safe

因此,请指定您要操作的类型( FirstCondition ):

final HolderClass<FirstCondition> holder = new HolderClass<>(new FirstProcessor(), new FirstCondition());
holder.getProcessor().process(holder.getCondition()); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM