简体   繁体   English

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

[英]Generics, Inheritance and Type Erasure problem

I can't wrap my head around, why the following code snippet including generics and wildcards is not valid. 我不能全神贯注,为什么下面的代码片段(包括泛型和通配符)无效。

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
    }

}

This fails with 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 Compilation failure .../test/App.java:[58,46] incompatible types: test.App.Condition cannot be converted to capture#1 of ? extends test.App.Condition

I already have read a lot about type erasure, but can anyone try to explain what's the actual problem and maybe provide an counter example why this is not allowed? 我已经阅读了很多有关类型擦除的信息,但是任何人都可以尝试解释实际的问题是什么,也许可以提供一个反例,说明为什么不允许这样做?

Thanks. 谢谢。

? extends ? extends used to declare a generic class is classic. 用来声明泛型类的? extends是经典的。 You use that to set the boundaries of your generic class. 您可以使用它来设置泛型类的边界。
But as you instantiate a generic type, you generally specify the type that you need to manipulate and you don't use still declare that with an upper bounded wildcard because this sets some rules that give you some possibilities (assignation it from subtypes variable) but also some constraints. 但是,在实例化泛型类型时,通常会指定需要处理的类型,并且不使用它仍然使用上限通配符来声明它,因为这会设置一些规则,从而为您提供一些可能性(从子类型变量赋值),但是还有些约束。

A example that should help you to understand : 一个应该可以帮助您理解的示例:

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

If you want to add numbers you declare : 如果要添加数字,请声明:

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

In a general way, a variable Foo<? extends Bar> 通常,变量Foo<? extends Bar> Foo<? extends Bar> cannot be invoked with a generic parameter for type safety reasons : 出于类型安全的原因,不能使用通用参数调用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

So specify the type that you manipulate ( FirstCondition ): 因此,请指定您要操作的类型( 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