Seltsamer Array-Rückgabetyp

Lesezeit: 3 Minuten

Benutzeravatar von Peter Lawrey
Peter Lawrey

Hat jemand das Array gesehen [] so nach der Methodensignatur platziert?

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

Drucke

[a, b, c, d, e]

In der Vergangenheit gab es seltsame Notationen für “C”-Kompatibilität, aber ich würde mir auch nicht vorstellen, dass jemand dies in C schreibt.

Weiß jemand warum das überhaupt erlaubt ist?

Ich verwende Java 7 Update 10, falls es darauf ankommt.

Dies macht dasselbe in Java 6. http://ideone.com/91rZV1


Übrigens wird dies nicht kompiliert, und ich würde es auch nicht erwarten

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

  • Ich könnte mir vorstellen, dass ein C-Programmierer diesen Schrecken schreibt. C++ ist bekannt für seine seltsame Syntax, wenn es um Typen geht, insbesondere um Array-Typen, insbesondere in Kombination mit Funktionszeigertypen.

    – John Dvorak

    7. Januar 2013 um 20:15 Uhr

  • Beachten Sie, dass inx x[10] ist genau das gleiche Problem, nur weniger übertrieben

    – John Dvorak

    7. Januar 2013 um 20:16 Uhr

  • Der Code wird nicht einmal kompiliert.

    – Roman C

    7. Januar 2013 um 20:23 Uhr

  • @RomanC Ich sehe kein Problem damit, dass eine Klasse beide hat toString und static toString(String). Sie haben jedoch Recht – haben diesen Aufruf nicht bemerkt oder den Methodennamen verdächtig gefunden.

    – John Dvorak

    7. Januar 2013 um 20:44 Uhr


  • Als ich Java lernte, tat ‘javap’ dies standardmäßig. Es hat mich immer verwirrt, warum (und das Lesen der Ausgabe viel schwieriger gemacht).

    – Owen

    13. Januar 2013 um 9:26 Uhr

Weiß jemand warum das überhaupt erlaubt ist?

In diesem Fall dient es der Abwärtskompatibilität mit Java selbst. Von dem JLS-Abschnitt 8.4:

Aus Gründen der Kompatibilität mit älteren Versionen der Java SE-Plattform darf die Deklaration einer Methode, die ein Array zurückgibt, (einige oder alle) der leeren Klammerpaare platzieren, die die Deklaration des Arraytyps nach der formalen Parameterliste bilden. Dies wird von der folgenden veralteten Produktion unterstützt, sollte aber nicht in neuem Code verwendet werden.

Und ja, Sie sollten es in der Tat als ein Gräuel betrachten, das keinen anderen Zweck hat, als andere Entwickler zu schockieren. Tatsächlich könnten Sie es verwenden, um auf Partys etwas Geld zu gewinnen, indem Sie darauf wetten, dass es sich zusammensetzt, gegen Leute, die es noch nie gesehen haben …

Hier ist die Art von Methode, von der aufrichtige Programmierer erwarten würden, dass sie ungültig ist:

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

  • @nicholas.hauschild Ich habe am Donnerstag ein Abendessen mit einer Gruppe von Java-Entwicklern. Das muss fast zählen. 😉

    – Peter Lawrey

    7. Januar 2013 um 20:19 Uhr

  • @PeterLawrey warum nicht (String[]... evil[])?

    – John Dvorak

    7. Januar 2013 um 20:22 Uhr

  • @PeterLawrey: Ich habe versucht, beide zu mischen, bekam aber: “Legacy-Array-Notation für Parameter mit variabler Arität nicht zulässig”

    – Jon Skeet

    7. Januar 2013 um 20:22 Uhr

  • @JanDvorak Die meisten Entwickler sind meiner Meinung nach ziemlich gut darin, statische Analysen und Compiler-Warnungen zu ignorieren.

    – Peter Lawrey

    7. Januar 2013 um 20:58 Uhr

  • @PeterLawrey Es gibt einen Unterschied zwischen einem “bloßen” gelben Dreieck in der linken Rinne und einer durchgezogenen schwarzen Linie über dem gesamten Methodennamen. Letzteres kann man nicht so einfach übersehen.

    – John Dvorak

    7. Januar 2013 um 21:01 Uhr

Es ist wie

  String[] a; 

ist das gleiche wie

  String a[];

Dasselbe gilt für die Syntax von Methodenrückgabetypen

  public static String mySplit(String s)[] {

ist das gleiche wie

  public static String[] mySplit(String s) {

Aber ich glaube, ich habe die von Ihnen erwähnte Version noch nie im produktiven Code gesehen.

  • Ich glaube, ich habe es auch noch nie gesehen; sollte ich, ich poste auf TDWTF

    – John Dvorak

    7. Januar 2013 um 20:19 Uhr

Ich denke, es ist der gleiche Grund, warum die folgenden Variablendeklarationen beide gleichwertig sind

String[] array
String array[]

Dies ist eine Sache, die C-Entwickler tun, also wurde es hinzugefügt, um ihnen zu helfen.

  • “Das ist eine Sache, die C-Entwickler tun, also wurde es aufgenommen, um ihnen zu helfen.” <-- Wenn Sie Literatur zu diesem bestimmten Punkt hätten, hätte ich gerne Hinweise, es könnte eine lustige Lektüre sein! (besonders seit ich tat C vor und konnte die Java-Notation am Anfang für mein ganzes Leben nicht verstehen)

    – fg

    7. Januar 2013 um 20:23 Uhr


Ich glaube, es sagt Java nur, dass der Rückgabetyp ein Array von ist Stringsdasselbe wie deklarieren

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

Ähnlich wie beim Deklarieren von Variablen:

String myStringArray[];

ist äquivalent zu

String[] myStringArray;

Gute Frage; Als ich einen Java-Parser implementierte, war ich an dieser Stelle wirklich verwirrt von der JLS-Grammatik.

Um Johns Antwort zu erweitern, hier ist, was los ist:

Es gibt (mindestens) 5 Stellen, an denen dies von Bedeutung ist:

  • Methodentyp-Signaturen
  • lokale Variablendeklarationen
  • Felddeklarationen
  • formale Parameter
  • for-Schleifen

Hier ist ein Auszug aus der Grammatik, der sich auf Methodendeklarationen konzentriert:

MethodOrFieldDecl:
    Type Identifier MethodOrFieldRest

MethodOrFieldRest:  
    FieldDeclaratorsRest ;
    MethodDeclaratorRest

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

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

(Achtung: Es ist schwierig, die Grammatik zu lesen, da die eckigen und geschweiften Klammern manchmal Literale und manchmal Metazeichen sind.)

Dies zeigt, dass [] kann sowohl unter dem erscheinen Type Regel und als Teil der MethodDeclaratorRest Regel. Es ist an beiden Orten optional.

Ahmed Katos Benutzer-Avatar
Ahmed Kato

Ja, das ist erlaubt,

gleichen Grund, dass:

String[] myArray;

ist äquivalent zu

String myArray[];

1424500cookie-checkSeltsamer Array-Rückgabetyp

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy