泛型超级与扩展 [英] Generics super vs. extends

查看:133
本文介绍了泛型超级与扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class Organic< E> {
void react(E e){}
static void main(String [] args){
// 1:Organic <?延伸有机> compound = new Aliphatic< Organic>();
// 2:有机<?超级脂肪族> compound = new Aliphatic< Organic>();
compound.react(new Organic());
compound.react(new Aliphatic());
compound.react(new Hexane());
}}
class Aliphatic< F>延伸有机F> {}
class正己烷< G>延伸脂肪族< G> {}

它说,如果第一行没有注释,下面的代码不会被编译:

  compound.react(new Organic()); 
compound.react(new Aliphatic());
compound.react(new Hexane());

如果第2行被取消注释,则以下内容将无法编译:

  compound.react(new Organic()); 

在第二个例子中,Aliphatic和它的超类型是允许的。那么为什么不是脂肪允许的呢?

在第一个例子中,为什么不是新的有机允许?

第一次编译错误:
$ b

   - 方法react(capture# 1-β延伸的有机物)在有机<1号捕获剂中>延伸有机>不适用于参数(有机)
- 该方法在有机<捕获#2>类型中反应(捕获#2→有机延伸)延伸有机>不适用于参数(脂肪族)
- 反应方法(捕获#3-of?延伸有机)在类型Organic <捕获#3>延伸有机>不适用于参数(Hexane)

第二个编译器错误:

   - 该方法在Organic 类型中反应(捕获#1超脂肪族)超级脂肪族>不适用于参数(有机)


解决方案

声明

 有机<?延伸有机>复合

表示复合 可以有机及LT; SomeSubtypeOfHexane> (因为脂肪族延伸有机 Hexane 扩展 Aliphatic SomeSubtypeOfHexane extends Hexane )。



在这种情况下, compound.react(new Organic()) compound.react(new Aliphatic()) compound.react(new Hexane())复合必须是 SomeSubtypeOfHexane (或其子类型)。






您的第二个声明

 有机<?超级脂肪族>复合

表示 compount 可以是有机<脂肪>



在这种情况下复合。因为 E 必须是 Aliphatic ,所以反应(新Organic())会导致类型错误$ c $(或其子类型)。




请记住,使用 A <?扩展B> A< ;?超级B>




  • 扩展可分配给它的对象数量,结果是,
  • 限制了可以对变量进行的操作。



由于该类的确切类型是未知的(只知道一个约束),因此编译器在安全方面犯错,并且不允许某些不共存或逆转的操作。 (如果你不熟悉它,合作和逆变是科学的这些类型的泛型的背景。)


Just when I thought I finally understood generics, I came across the following example:

public class Organic<E> {
          void react(E e) { }
          static void main(String[] args) {
            //1: Organic<? extends Organic> compound = new Aliphatic<Organic>(); 
            //2: Organic<? super Aliphatic> compound = new Aliphatic<Organic>(); 
           compound.react(new Organic());
           compound.react(new Aliphatic());
           compound.react(new Hexane());
 } }
 class Aliphatic<F> extends Organic<F> { }
 class Hexane<G> extends Aliphatic<G> { }

It says, if line 1 is uncommented, the following will not compile:

  compound.react(new Organic());  
  compound.react(new Aliphatic());  
  compound.react(new Hexane());

while if line 2 is ucommented, the following will not compile:

compound.react(new Organic());

In the second example, Aliphatic and it's supertypes are allowed. So why isn't Aliphatic allowed?

In the first example, why isn't new Organic allowed??

1st compiler error:

- The method react(capture#1-of ? extends Organic) in the type Organic<capture#1-of ? extends Organic> is not applicable for the arguments (Organic)
- The method react(capture#2-of ? extends Organic) in the type Organic<capture#2-of ? extends Organic> is not applicable for the arguments (Aliphatic)
- The method react(capture#3-of ? extends Organic) in the type Organic<capture#3-of ? extends Organic> is not applicable for the arguments (Hexane)

2nd compiler error:

- The method react(capture#1-of ? super Aliphatic) in the type Organic<capture#1-of ? super Aliphatic> is not applicable for the arguments  (Organic)

解决方案

Your first declaration

Organic<? extends Organic> compound

means that compound could be an Organic<SomeSubtypeOfHexane> (since Aliphatic extends Organic, Hexane extends Aliphatic and SomeSubtypeOfHexane extends Hexane).

In that case, compound.react(new Organic()), compound.react(new Aliphatic()) and compound.react(new Hexane()) would lead to a type error, since E in compound must be a SomeSubtypeOfHexane (or subtype thereof).


Your second declaration

Organic<? super Aliphatic> compound

means that compount could be an Organic<Aliphatic>.

In that case compound.react(new Organic()) would lead to a type error, since E must be an Aliphatic (or subtype thereof).


Remember that declaring a variable using A<? extends B> or A<? super B>

  • extends the amount of objects that can be assigned to it, and, in consequence,
  • restricts what can be done with the variable.

Since the exact type of the class is unknown (only a constraint is known), the compiler has to err on the side of safety and disallow certain operations that are either not co- or contravariant. (If you are not already familiar with it, Co- and contravariance is the scientific background of these types of generics.)

这篇关于泛型超级与扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆