加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在Java中使用通配符和在抽象方法中声明泛型类型之间的区别

发布时间:2020-12-15 00:55:23 所属栏目:Java 来源:网络整理
导读:我试图理解 Java中的泛型类型,理论上它看起来是可以理解的,但是当我需要将它应用于实际代码时,我遇到了问题.我想声明将返回泛型类型的抽象方法.让我们假设我有一个名为Magicable的空接口,2类实现它:Magican和Witch. 现在我想知道这3个声明之间的区别是什么
我试图理解 Java中的泛型类型,理论上它看起来是可以理解的,但是当我需要将它应用于实际代码时,我遇到了问题.我想声明将返回泛型类型的抽象方法.让我们假设我有一个名为Magicable的空接口,2类实现它:Magican和Witch.
现在我想知道这3个声明之间的区别是什么:
/*1*/protected abstract <T extends Magicable> List<T> getMagicables();
/*2*/protected abstract List<? extends Magicable> getMagicables();
/*3*/protected abstract List<Magicable> getMagicables();

>在第一种情况下,当我想在某个扩展抽象类的类中实现此方法的主体时,我遇到了问题:

@Override
protected List<Magican> getMagicable() {..}

我有警告信息:

Type safety: The return type List<Magican> for getMagicable() from the type MagicanService needs unchecked conversion to conform to List<Magicable> from the type MagicableService.

>在第二种情况下,我没有这个警告,但我在抽象类中有问题,我在上面声明了抽象方法:

public void <T extends Magicable> T getOneFromList() {
      List<T> list = getMagicables();
      //.....
  }

在这种情况下,我在getMagicables()调用中有编译错误:

Type mismatch: cannot convert from List<capture#2-of ? extends Magicable> to List<T>

>第三种情况导致上述两个代码位置的编译错误.在我的情况下,我不认为它是否正确解决.

解决方法

  1. First case

只需声明您的方法:

@Override
    protected <T extends Magicable> List<T> getMagicables() {
       List<T> list = ...
       return list
    }

如果你真的想要这个:

@Override
    protected List<Magican> getMagicable() {..}

您可能必须将通用T声明为类定义

public abstract class AbstractKlass<T extends Magicable> {
        protected abstract List<T> getMagicables();
     }

然后在你的子类中:

public class MySubClass extends AbstractKlass<Magican> {

        @Override
        protected List<Magican> getMagicables() {
           ...
        }
     }
  1. Second case

编译错误是正常的,因为<?扩展Magicable>从方法的签名意味着你不关心列表中的内容,从你可以将这些元素视为可魔术的那一刻起.在打电话时

List<T> list = getMagicables();

你想在不知情的情况下照顾T型.换句话说,有3个用例:T是Magicable(OK),T是魔术师(错误因为getMagicables可能返回Witch列表)而T是Witch(也错了).

  1. Why I use ? extends Magicable instead of just Magicable in lists

因为List< Magician>是List&lt ;?的子类型扩展Magicable>但不是List< Magicable>的子类型.这对于方法的参数是有用的.

public void doIt(List<? extends Magicable> list) {
         // you can't add a Magician here
    }

可以用作

List<Witch> list = ...
    doIt(list);

但如果你有

public void doIt(List<Magicable> list) {
         // you can add a Magician here
    }

你不能用它

List<Witch> list = ...
    doIt(list); // compile error

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读