73

[]有没有人看到像这样放置在方法签名之后的数组?

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();
}
4

6 回答 6

90

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

在这种情况下,它是为了向后兼容 Java 本身。从JLS 第 8.4 节

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

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

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

public String[] mwahahaha(String[] evil[])[] {
    return evil;
}
于 2013-01-07T20:15:55.253 回答
19

就像是

  String[] a; 

是相同的

  String a[];

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

  public static String mySplit(String s)[] {

是相同的

  public static String[] mySplit(String s) {

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

于 2013-01-07T20:17:30.410 回答
6

我认为这是相同的原因,以下变量声明都是等价的

String[] array
String array[]

这是 C 开发人员所做的事情,所以它被包括在内以帮助他们。

于 2013-01-07T20:16:01.490 回答
4

我相信它只是告诉Java返回类型是一个数组Strings,与声明相同

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

类似于声明变量:

String myStringArray[];

相当于

String[] myStringArray;
于 2013-01-07T20:16:03.957 回答
4

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

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

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

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

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

MethodOrFieldDecl:
    Type Identifier MethodOrFieldRest

MethodOrFieldRest:  
    FieldDeclaratorsRest ;
    MethodDeclaratorRest

MethodDeclaratorRest:
    FormalParameters {[]} [throws QualifiedIdentifierList] (Block | ;)

Type:
    BasicType {[]}
    ReferenceType  {[]}

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

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

于 2013-01-08T23:22:36.143 回答
1

是的,这是允许的,

相同的原因:

String[] myArray;

相当于

String myArray[];
于 2013-01-08T09:19:47.653 回答