【问题标题】:Strange array return type奇怪的数组返回类型
【发布时间】:2012-12-21 14:47:08
【问题描述】:

有人见过像这样放在方法签名之后的数组[]吗?

public static String mySplit(String s)[] {
    return s.split(",");
}

public static void main(String... args) {
    String[] words = mySplit("a,b,c,d,e");
    System.out.println(Arrays.toString(words));
}

打印

[a, b, c, d, e]

过去,“C”兼容性的奇怪符号一直存在,但我也无法想象有人用 C 编写此代码。

有谁知道为什么甚至允许这样做?

我正在使用 Java 7 update 10,以防万一。

这在 Java 6 中做同样的事情。http://ideone.com/91rZV1


顺便说一句,这不会编译,我也不希望它编译

public static <T> List mySplit(String s)<T> {
    return Collections.emptyList();
}

【问题讨论】:

  • 我可以想象一个 C 程序员写出这种可怕的东西。 C++ 在涉及类型时以其怪异的语法而闻名,尤其是数组类型,尤其是与函数指针类型结合使用时。
  • 请注意,inx x[10] 是完全相同的问题,只是不那么夸张
  • 代码甚至无法编译。
  • @RomanC 我没有看到一个类同时具有toStringstatic toString(String) 的问题。但是,您是对的 - 没有注意到此调用或发现方法名称可疑。
  • 当我学习 Java 时,'javap' 默认是这样做的。它总是让我感到困惑(并且使阅读输出变得更加棘手)。

标签: java arrays syntax declaration


【解决方案1】:

有谁知道为什么甚至允许这样做?

在这种情况下,它是为了向后兼容 Java 本身。来自JLS section 8.4

为了与旧版本的 Java SE 平台兼容,返回数组的方法的声明允许在形式参数列表之后放置(部分或全部)构成数组类型声明的空括号对.以下过时产品支持此功能,但不应在新代码中使用。

是的,您确实应该将其视为一种可憎的东西,除了震惊其他开发人员之外没有任何其他目的。实际上,你可以用它在派对上赢一些钱,赌它会编译,对抗那些从未见过它的人......

以下是正确的编码人员认为无效的方法:

public String[] mwahahaha(String[] evil[])[] {
    return evil;
}

【讨论】:

  • @nicholas.hauschild 星期四我正在与一群 Java 开发人员共进晚餐。这几乎要数了。 ;)
  • @PeterLawrey 为什么不(String[]... evil[])
  • @PeterLawrey:我尝试将两者混合,但得到:“可变参数参数上不允许使用旧数组表示法”
  • @JanDvorak 大多数开发人员都非常擅长忽略我发现的静态分析和编译器警告。
  • @PeterLawrey 左侧装订线中的“纯”黄色三角形和整个方法名称中的实线黑线之间存在差异。你不能轻易错过后者。
【解决方案2】:

我认为下面的变量声明都是等价的原因是一样的

String[] array
String array[]

这是 C 开发人员所做的事情,因此包含在内是为了帮助他们。

【讨论】:

  • “这是 C 开发人员所做的事情,因此包含在内是为了帮助他们。” 做过 C 并且一开始我一生都无法理解 Java 表示法)
【解决方案3】:

相信只是告诉Java返回类型是Strings的数组,和声明一样

static String[] mySplit(String s) {...

类似于声明变量:

String myStringArray[];

等价于

String[] myStringArray;

【讨论】:

    【解决方案4】:

    好像

      String[] a; 
    

    一样
      String a[];
    

    同样适用于方法返回类型的语法

      public static String mySplit(String s)[] {
    

    一样
      public static String[] mySplit(String s) {
    

    但我想我还没有看到你在生产代码中提到的版本。

    【讨论】:

    • 我想我也没见过;我应该发帖到 TDWTF
    【解决方案5】:

    是的,这是允许的,

    同样的原因:

    String[] myArray;
    

    等价于

    String myArray[];
    

    【讨论】:

      【解决方案6】:

      好问题;当我实现一个 Java 解析器时,我记得当时被 JLS 语法弄糊涂了。

      为了扩展约翰的答案,这是发生了什么:

      • 这在规范中称为"mixed notation"
      • grammar 将类型声明分成两部分,每部分可能有 0 个或多个 []s

      (至少)有 5 个地方很重要:

      • 方法类型签名
      • 局部变量声明
      • 字段声明
      • 形式参数
      • for-loops

      这里是语法的摘录,重点是方法声明:

      MethodOrFieldDecl:
          Type Identifier MethodOrFieldRest
      
      MethodOrFieldRest:  
          FieldDeclaratorsRest ;
          MethodDeclaratorRest
      
      MethodDeclaratorRest:
          FormalParameters {[]} [throws QualifiedIdentifierList] (Block | ;)
      
      Type:
          BasicType {[]}
          ReferenceType  {[]}
      

      (警告:由于方括号和大括号有时是文字,有时是元字符,因此很难阅读语法。)

      这表明[] 既可以出现在Type 规则下,也可以作为MethodDeclaratorRest 规则的一部分出现。在这两个地方都是可选的。

      【讨论】:

        猜你喜欢
        • 2017-05-20
        • 1970-01-01
        • 2011-04-08
        • 2014-11-26
        • 2013-10-14
        • 2020-04-25
        • 1970-01-01
        • 1970-01-01
        • 2020-12-17
        相关资源
        最近更新 更多