当前位置: 首页 > 面试题库 >

返回类型的Java界通配符

宇文兴言
2023-03-14
问题内容

我在很多地方都读过,包括在方法返回类型中使用有界通配符是一个坏主意。但是,我在课堂上找不到避免这种情况的方法。我想念什么吗?

情况看起来像这样:

class EnglishReaderOfPublications {

    private final Publication<? extends English> publication;

    EnglishReaderOfPublications(Publication<? extends English> publication) {
        this.publication = publication;
    }

    void readPublication() {
        publication.omNomNom();
    }

    Publication<? extends English> getPublication() {
        return publication;
    }
}

总而言之,这是一个我希望能够 使用
任何与英语有所不同的出版物的类。该类需要允许从外部访问发布,但理想情况下,的调用者getPublication不希望将结果用作有界通配符。他们会很高兴的Publication<English>

有办法解决吗?


问题答案:

有界通配符具有传染性,这就是您链接到的页面似乎在哀叹。好吧,无可否认……但是我想我并不认为这是一个大问题。

在很多情况下,正是 由于
有传染性,我才返回有界通配符。JDK的好坏(我说的更糟,但这是一个不同的肥皂盒:))没有只读集合的​​接口。如果我返回了一个List<Foo>我不希望别人修改的代码(甚至可以安全地包装在中Collections.unmodifiableList),则无法在返回签名中声明。作为穷人的解决方法,我经常回去List<? extends Foo>。仍然可以尝试通过删除元素或插入来修改该列表null,但是至少您不能add(new Foo())提醒您该列表可能是只读的。

更笼统地说,如果您确实希望调用站点对对象的访问受到限制,则返回具有有限返回类型的东西是完全合理的。

另一个示例是线程安全队列,您将其移交给其他线程,其中一个线程是生产者,另一个线程是使用者。如果给生产者a Queue<? super Foo>,很显然,您打算让他们将物品放入其中(而不是取出物品)。同样,如果给消费者一个Queue<? extends Foo>,很显然,您打算让他们取出物品(而不放入物品)。



 类似资料:
  • 问题内容: Java通常可以基于参数(甚至与返回类型(例如,与C#相反))来推断泛型。 恰当的例子:我有一个通用类,它只存储一对值,并且可以按以下方式使用: 该方法如下所示: 非常好。但是,这不再适用于以下需要通配符的用例: (请注意显式强制转换以进行正确的类型。) 代码失败,并显示以下错误(由Eclipse提供): 类型不匹配:无法从转换为 但是,显式调用构造函数仍然可以按预期工作: 有人可以解

  • 问题内容: 考虑以下代码: 编译器抱怨正在尝试对行为进行存根的行。关于如何使用存根方法返回带有有界通配符的类型的任何指针? 问题答案: 您也可以为此使用非类型安全方法doReturn, 正如在Mockito的Google组中讨论的那样。 尽管它比起来简单,但再次请注意,它不是类型安全的。如果您担心类型安全,那么米尔豪斯的答案是正确的。 额外细节 要明确的是,这是观察到的编译器错误, 我相信编译器已

  • 问题内容: 最近,我读了这篇文章:http : //download.oracle.com/javase/tutorial/extra/generics/wildcards.html 我的问题是,而不是创建像这样的方法: 我可以创建一个这样的方法,它可以正常工作: 我应该使用哪种方式?通配符在这种情况下有用吗? 问题答案: 这取决于您 需要 做什么。如果要执行以下操作,则需要使用bounded t

  • 上限通配符下限通配符 有人能帮我理解一下吗?

  • 我不确定这在Java中是否可行。而且,我也不知道该在谷歌上查询什么。无论如何,我想要一个方法,它将一个类(接口或类)作为参数,并且该方法的返回类型是该类的一个实例。我不想事后重铸一个物体。 我不确定这个功能是否存在,或者语法是什么。假设我有一个名为XYZ的类,这是我的伪方法。 现在假设XYZ是某种通用语法。这在Java中可能吗?谢谢你的帮助。

  • 问题内容: 您好直接从Oracle http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html提供的Java教程中 我知道编译时的类型擦除。而且我也知道,一个类型(无界)将被Object取代。知道在编译时如何使用无界通配符进行编译吗?只是删除它,因为它是原始类型? 提前致谢。 问题答案: 假设我们有一个