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

具有与通用类型无关的通用方法的原始类型

郤坚诚
2023-03-14
问题内容

这是hrert的问题Generic类与其他类型的Collectiongetter的后续文章。如果您可以为我的问题找到更好的标题,请随时对其进行编辑:

下面的代码包含一个GenericClass<T>具有返回类型方法的通用类和具有返回类型方法的T另一个方法,Collection<String>显然与T

现在,如果我实例化一个原始数据GenericClass(我永远不会做,所以这个问题更多是一个理论问题,以帮助理解正在发生的事情),那么在增强的for循环中调用该方法将不起作用,因为似乎所有通用类型信息使用原始类型时迷路。但是,当在赋值中调用相同的方法时,它就起作用了(它警告类型不安全,但会编译)。

以我的观点,要么两者都不起作用,要么两者都应该起作用。我不明白为什么一个有效,而另一个无效。您是否有任何提示,或者知道JLS的任何部分可以解释此行为?

public class GenericClass<T>  {

    T doSomething() {
        return null;
    }

    Collection<String> getCollection() {
        return Collections.emptyList();
    }

    public static void main(String[] args) {
        GenericClass raw = new GenericClass();
        // This will not compile (Error message below)
        for (String str : raw.getCollection()) {
            // Type mismatch: cannot convert from element type Object to String
        }
        // This is only a warning:
        // Type safety: The expression of type Collection needs unchecked conversion to conform to Collection<String>
        Collection<String> coll = raw.getCollection();
        for (String string : coll) {
            // works just fine
        }
    }
}

有一个相关的问题,再加上此处的公认答案,可以很好地说明正在发生的事情:为什么这种通用的Java代码无法编译?


问题答案:

在第一种情况下,raw.getCollection()返回raw Collection。 JLS
14.14.2
指定了增强for循环的类型检查:

如果Type(在FormalParameter生产中)是引用类型,则TargetType为Type;否则,Type为Type。否则,TargetType是I的类型参数
或Object(如果我是raw 的)的捕获转换的上限

(添加了重点)

在第二种情况下,您正在将原始类型显式分配给泛型类型,这可以通过正常警告来允许。



 类似资料:
  • 问题内容: 考虑以下方法: 和 这两种方法有什么区别?如果没有差异,为什么要使用第二个? 问题答案: 不允许您在列表中添加对象。请参阅下面的程序。这是我们传递给method的特定列表类型。 特定方式,列表是使用特定类型创建的,并传递给method 。不要与 单词 混淆。 具体可以是任何普通对象,例如Dog,Tiger,String,Object,HashMap,File,Integer,Long

  • 问题内容: 我正在尝试创建一个通用类型,该通用类型保留已创建的自身版本的地图以供以后使用。实际上,这是一种单例模式,其中每种类型都有一个实例。到目前为止,我的代码是: 但是,我仍然不确定我是否“做对了”。感觉我应该能够指定该集合为(类-> FieldBinder)。IDE警告有关return语句的事实只会加强这种想法。 有没有更好的方法来解决这个问题? 注意:这个问题似乎密切相关,但是距离足够远,

  • 问题内容: 假设我有一个超类,它定义了以下抽象方法 现在,如果我想在某些子类中覆盖它 我收到有关类型安全和未经检查的转换的警告: 类型安全:返回类型为从类型需要选中转换,以符合从类型 没有下摔倒,如果?有什么办法可以适当消除警告吗? 问题答案: 重写方法的返回类型必须是重写方法的返回类型的子类型。 不是where 的子类型。T在这里未知。 是每个子类型化规则的的子类型。 有关通配符的一些子类型化规

  • JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟原始类型不是对象(在这里我们会分析地更加清楚)。 我们来看看原始类型和对象之间的关键区别。 一个原始值: 是原始类型中的一种值。 在 JavaScript 中有 7 种原始类型:string,number,bigint,

  • 问题内容: 使用泛型时,我发现了一个奇怪的行为。 在此类中,该成员与以下内容无关: 该类在main中使用: 编译错误为“类型不兼容。必需:找到的字符串:对象”。 似乎Java忘记了使用原始类型时的type参数。 我的Java版本是1.7.0_21 问题答案: 简而言之,由于是原始的,它的非静态成员也变为原始的。 JLS§4.8中对此进行了概述: 更准确地说,原始类型定义为以下之一: 通过采用通用类

  • 问题内容: 最近,我读了一段对我来说似乎很奇怪的代码。众所周知,在需要使用集合时,需要初始化它们的泛型类型。此外,我们知道集合可以包含集合作为其元素。 代码: 我的问题是 我们为什么要使用它来创建对象,因为我们没有为集合提供元素的实际类型。 为什么我们要使用集合“结果”添加到集合中,而“结果”只是一个简单的集合。我们没有把它定义为一个的 问题答案: Java通用集合没有存储类型,以确保与J2SE