【问题标题】:No error when using generic class without defining a type在不定义类型的情况下使用泛型类时不会出错
【发布时间】:2013-08-21 23:07:41
【问题描述】:

为什么编译器不产生任何错误?我可以在 JLS 的什么地方了解到这种情况?

class Main {
  public static void main(String[] args) {
    A a = new A();

    List<Integer> list = a.getStrings();
  }

  static class A<X> {
    public List<String> getStrings() {
      return new ArrayList<String>();
    }
  }
}

【问题讨论】:

  • 这段代码是执行(没有错误)还是只编译?
  • 我最近看到了这个问题。基本上,当您使用不带类型参数的A 时,编译器就像A 中没有使用泛型一样。这是向后兼容的事情。
  • 你使用的是原始的A 类,这对于向后兼容来说并没有错
  • jls 7 --> 4.8 Raw Type

标签: java generics types


【解决方案1】:

您可以在JLS §4.8阅读有关这种情况的信息:

仅允许使用原始类型作为对遗留代码兼容性的让步。强烈反对在将泛型引入 Java 编程语言之后编写的代码中使用原始类型。 Java 编程语言的未来版本可能会禁止使用原始类型。

为确保始终标记可能违反类型规则的行为,对原始类型成员的某些访问将导致编译时未经检查的警告。访问原始类型的成员或构造函数时编译时未检查警告的规则如下:

  • 在分配给字段时:如果左侧操作数的类型是原始类型,则如果擦除更改了字段的类型,则会出现编译时未经检查的警告。

  • 在调用方法或构造函数时:如果要搜索的类或接口的类型(第 15.12.1 节)是原始类型,则如果擦除更改了任何形式参数类型,则会出现编译时未经检查的警告方法或构造函数。

  • 当形式参数类型在擦除下没有改变(即使结果类型和/或 throws 子句改变)、从字段读取或创建类实例时,方法调用不会发生编译时未经检查的警告原始类型。

【讨论】:

    【解决方案2】:

    这就是所谓的使用原始类型。由于泛型并非始终是 Java 的一部分,因此使用该语言是出于遗留原因。

    而且由于您不使用泛型类型参数,它只会被删除。正如评论者指出的那样,如果您在类型擦除后不指定类型参数,它将是Object

    【讨论】:

    • 当没有明确指定泛型类型时,我认为它默认为Object
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多