Angelika Langer GenericsFAQ - Can i use raw type as any other type?

本秂侑毒 提交于 2020-02-04 05:27:05

问题


I am reading through documentation of AgelikaLangerDoc. I have just started reading this article. I have seen the following syntax in the code.

interface Copyable<T>{
  T copy();
}

final class Wrapped<Elem extends Copyable<Elem>>{
}

I am not able to understand the following generics syntax meaning.

<Elem extends Copyable<Elem>>

I know its pretty basic but really generics is tricky. Why do we need to put it like this? We could have said something ike

final class Wrapped<Copyable<Elem>>{
}

I know its not legal but even the above syntax is not easy to understand. Can someone explain this part?


回答1:


The declaration:

class Wrapped<Elem extends Copyable<Elem>>

simply says that you can only instantiate Wrapped type with a subtype of Copyable. Note the Elem part. It means that the subtype Elem should be a subtype of Copyable<Elem>.

For e.g., suppose you have a class that implements that generic interface:

interface Copyable<T>{
    T copy();
}

class CopyableImpl implements Copyable<CopyableImpl> {
    CopyableImpl copy() { ... }
}

Now you can instantiate the Wrapped generic type with CopyableImpl like this:

Wrapped<CopyableImpl>

Replace CopyableImpl with Elem and see whether it satisfies the declaration.

CopyableImpl extends Copyable<CopyableImpl>
Elem extends Copyable<Elem>  

So, it is a valid type argument for Wrapped.


However, if your class is something like this:

class SomeCopyable implements Copyable<OtherCopyable> {
    OtherCopyable copy() { ... }
} 

you cannot instantiate Wrapped generic type with this class, since it does not satisfy the type parameter for Wrapped.

SomeCopyable extends Copyable<OtherCopyable>
Elem extends Copyable<Elem2>  // Elem 2 is different from Elem

As for your proposal:

class Wrapped<Copyable<Elem>>

no this declaration is completely different from the original one. Considering the fact that generic types are invariant, in the sense, a List<String> is not a subtype of List<CharSequence> even though String is a subclass of CharSequence. So, for this declaration, you can only instantiate the Wrapped type with Copyable type argument like this:

Wrapped<Copyable<String>>
Wrapped<Copyable<Integer>>

Wrapped<CopyableImpl>  // Wrong. This doesn't match the type declaration.

Further Reading:

  • Angelika Langer - How do I decrypt "Enum<E extends Enum<E>>"?


来源:https://stackoverflow.com/questions/18444652/angelika-langer-genericsfaq-can-i-use-raw-type-as-any-other-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!