我试图理解 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

在Java中使用通配符和在抽象方法中声明泛型类型之间的区别的更多相关文章

  1. ios – 如何在Swift中使用没有类型参数的泛型类?

    解决方法Swift还不像Java那样支持wildcard-stylegenerics(即Animal

  2. ios – NSURLProtocol的抽象方法

    我一直在我的应用程序中使用自定义NSURLProtocol来检测资源并从缓存目录加载(如果可用),或重定向回我的应用程序的服务器.但是,我发现缺少抽象方法的文档,我不知道如何处理我们需要实现的一些抽象方法.我们必须实施:canInitWithRequest很简单,这就是告诉NSURLProtocol您将响应此请求的方式.我不知道如何处理canonicalRequestForRequest:在sta

  3. ios – 如何在Swift中向下转换/转换结构的泛型类型

    我是否必须将这些存储为Any的数组,然后每次都将它们转换为或者我只是误解某些(或两者)?

  4. ios – 在XCTestCase子类中使用泛型有效吗?

    我有一个XCTestCase子类,看起来像这样.为了简洁起见,我已经删除了setup()和tearDown方法:它的子类看起来像这样:在理论上,这应该按预期工作–编译器不会抱怨任何事情.但是只是当我运行测试用例时,setup()方法甚至没有被调用.但是,它表明当testName()方法应该失败时,测试已经过去了.使用泛型是一个问题吗?我可以很容易地想到很多非通用的方法,但是我很想写这样的测试用例.这是XCTest在Objective-C和Swift之间的互操作性?Ergo您的通用XCTestCase子类不

  5. 泛型 – Xcode构建错误时,我添加枚举到泛型类?

    为什么在将泛型类添加到枚举时会收到错误:错误:但是当我这样做时,我没有收到错误:或这个:解决方法您不能将任何类型嵌套在通用的类型中,反之亦然.换句话说,你不能像类,结构和枚举这样做的事情:和乃至苹果人explained的限制原因:It’sanimplementationlimitation.We’llremovetherestrictiononceourcompilerandruntimearea

  6. ios – 如何通过Swift中的泛型类型构造一个属性?

    我在swift中创建了一个泛型类,我想使用“AdaptorType”类型初始化一个适配器,但是我收到一个编译错误我也尝试在init()中初始化它,但是同样的问题在于使用通用类型AdaptorType初始化适配器属性的正确方法是什么?

  7. ios – Equatable实现似乎不适用于泛型

    我仍然在与Swift仿制药作斗争.今天我发现我的Equatable协议实现不起作用,如果它是从泛型类调用的.我的模特课:类,使用泛型类型:它的子类:当我调用TrackingCache实例的removeEntities方法时,我总是在输出中得到相等的:false,即使id是相同的.但是,如果我直接将方法移动到TrackingCache类,它似乎工作正常!

  8. 泛型 – MonoTouch和支持变体通用接口

    如果是这样,MonoTouch中针对这种情况的推荐解决方法是什么?解决方法这实际上取决于编译器而不是Mono版本.IOW有些东西可能适用于Mono2.10而不适用于MonoTouch6.x.当前版本的MonoTouch附带了smcs编译器和基于2.1的配置文件.较新的功能,如协方差,需要一个完整的4.0编译器和运行时.未来版本的MonoTouch将提供4.0/4.5运行时和编译器.

  9. 什么是我的iOS配置门户中的(Xcode:通配符AppID)?

    突然之间,我在我的中看到了一个新的AppID,其中包含的描述,Apple最近是否添加了它?此应用程序没有(配置)链接,只有链接,我无法配置任何东西!问候解决方法Xcode现在可以自动创建配置文件,因此您不必这样做.此通配符应用程序ID是该配置文件的一部分.

  10. 寒城攻略:Listo 教你 25 天学会 Swift 语言 - 24 Generics

    它可以避免重复的代码,用一种清晰和抽象的方式来表达代码的意图//泛型是Swift强大特征中的一个,许多Swift标准库都是通过泛型代码构建出来的。{forinenumerate{//遍历索引固定字符串的下标ifvalue==valuetoFind{returnindex}}returnnil}letstrings=["cat","dog","llama","parakeet"]ifletfoundindex=findStringIndex{p

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部