Java自绑定泛型

Java自绑定泛型,java,generics,Java,Generics,我有自界泛型,比如: public interface SelfConfigurable<E extends SelfConfigurable<E>> { E configure(JsonObject settings); } 公共接口自配置{ E配置(JsonObject设置); } 还有另一个接口,也是泛型的,它扩展了我以前的接口: public interface ConfigurableSegmentFilter<T> extends Se

我有自界泛型,比如:

public interface SelfConfigurable<E extends SelfConfigurable<E>> {
    E configure(JsonObject settings);
}
公共接口自配置{
E配置(JsonObject设置);
}
还有另一个接口,也是泛型的,它扩展了我以前的接口:

public interface ConfigurableSegmentFilter<T> extends SegmentFilter<T>, SelfConfigurable<ConfigurableSegmentFilter<T>> {
}
公共接口可配置SegmentFilter扩展了SegmentFilter,可自行配置{
}
我也有这样一个实现

public abstract class ConfigurableSegmentFilterSkeleton<T> implements ConfigurableSegmentFilter<T> {
    @Override
    public ConfigurableSegmentFilter<T> configure(JsonObject settings) {
     ... }
}
公共抽象类ConfigurableSectionFilterskeleton实现ConfigurableSectionFilter{
@凌驾
公共可配置分段筛选器配置(JsonObject设置){
... }
}
我正在通过反射实例化对象,并希望在添加到列表之前对其进行配置:

List<ConfigurableSegmentFilter<?>> result = ...

ConfigurableSegmentFilter newFilter = Reflection.newInstance() + casting

result.add(newFilter.configure(...)); <-- compile error 'cannot be applien to SelfConfigurable' but why?

//when i call to configure directly i am getting:
SelfConfigurable configure = newFilter.configure(...) <-- why SelfConfigurable??

List如果“原始”类型与泛型类型参数设置为“对象”,则“原始”类型与泛型类型并不相同

这样做的原因是为了避免运行时强制转换异常

例如,让我们考虑一个更简单的场景,包括“java .UTI.List'类:

List a = ... # a elements could be a mix of any type.
List<?> b = ... # b elements are all instance of a known class '?'.
List<Object> c = ... # c elements are all instances of Object.
List<String> d = ... # d elements are all instances of String.
“?”此处表示未知类型。。。例如,它可以是String,在这种情况下,我们回到了清晰的情况c->d。设置此限制的原因是为了防止在其他代码段实际知道集合的类型参数(如String)并且正在使用它元素时出现运行时异常,从而导致运行时强制转换异常

  • b、 a,d->c或b,c,d->a

    允许,不管怎样,所有实例都是“对象”,所以没有问题。a

  • 还请注意,某些引用可能是一个问题(至少是一个警告):


    当您使用原始类型的表达式时,您将“关闭”对该表达式所做的所有操作中的泛型,包括方法签名和超类型签名。这意味着,原始类型
    configurableSectionFilter
    仅扩展原始类型
    自配置
    ,其实例方法
    .configure()
    因此返回对
    E
    的擦除,即
    自配置


    这就是为什么您应该避免使用原始类型,因为它们只是为了向后兼容。当类型参数未知时,可以使用通配符参数化类型。

    编译器错误的发生是因为您使用的是原始类型。请参见标题“原始类型是该类型的擦除”。什么是
    JinniSegmentFilter
    ??对不起,我错误地添加了它。我知道我使用的是原始类型,但无论如何我无法理解它背后的逻辑。ConfigurableSegmentFilter应与ConfigurableSegmentFilter相同,后者等于ConfigurableSegmentFilter,完全没有绑定。@Gelerion否,ConfigurableSegmentFilter与ConfigurableSegmentFilter as不一样?可以代表任何东西(例如字符串)。在泛型中,即使B扩展了A,Clazz也不能从Clazz赋值。这似乎有悖常理,但围绕着无效运行时强制转换异常,这是有原因的。@Gelerion我不得不说,我很惊讶您在结果中没有得到错误。添加(…)。我认为编译器无法判断这两个“?”引用的是同一类型。这真的是手头问题的所有相关代码吗?还是您省略了一些代码?谢谢您的回答和解释。我知道“原始”类型与通配符泛型不同。我读了《Java泛型和集合》一书,但无论如何,我不明白在我的具体案例中有什么不同。我没有省略任何相关的代码,只是在一个新的干净项目和newFilter上尝试了它。当我使用原始对象而不是通配符绑定对象时,configure(..)返回我SelfConfigurable。也许是因为桥法?
    List a = ... # a elements could be a mix of any type.
    List<?> b = ... # b elements are all instance of a known class '?'.
    List<Object> c = ... # c elements are all instances of Object.
    List<String> d = ... # d elements are all instances of String.
    
    b.addAll(c); // error!!!
    
       c = a; // unchecked warning; 
       c = d; // error as now you would be able to add non-strings to 'd' thru 'c'.
       c = b; // error, same as above where the the element type is unknown.
       a = d; a = b; // same as with 'c'.
       d = c; d = a; // error for obvious reason.