Frage

Die folgende Methode funktioniert nicht, da der innere Block eine Variable mit dem gleichen Namen wie ein im äußeren Block deklariert. Offenbar gehören Variablen die Methode oder Klasse, in der sie deklariert sind, nicht auf den Block, in dem sie deklarieren sind, so deshalb kann ich nicht einen kurzen wenig vorübergehenden Block für das Debuggen schreiben, die eine Variable in dem äußeren Umfang weg zu schieben geschehen in Schatten nur für einen Moment:

void methodName() {
  int i = 7;
  for (int j = 0; j < 10; j++) {
    int i = j * 2;
  }
}

Fast jede Block-scoped Sprache, die ich jemals, einschließlich trivial wenig unterstützten Sprachen verwendet habe, die ich Interpreter und Compiler für in der Schule geschrieben. Perl kann dies tun, ebenso Schema und sogar C. Auch PL / SQL unterstützt das!

Was ist der Grund für diese Design-Entscheidung für Java?

Edit: wie jemand darauf hingewiesen, Java hat Block-Scoping. Was ist der Name für das Konzept zu frage ich? Ich wünschte, ich mehr von diesen sprach Design-Klassen erinnern konnte. :)

War es hilfreich?

Lösung

Ich glaube, der Grund dafür ist, dass die meisten der Zeit, dass nicht beabsichtigt ist, ist es eine Programmierung oder logische Fehler ist.

in einem Beispiel so trivial, wie Ihre, seine Hand, aber in einem großen Block von Code, versehentlich eine Variable erneut deklariert werden möglicherweise nicht offensichtlich sein.

ETA: es könnte auch auf die Ausnahmebehandlung in Java zusammenhängen. Ich dachte, einen Teil dieser Frage in einer Frage diskutiert wurde im Zusammenhang mit, warum in einem Try-Abschnitt deklarierten Variablen waren in dem Fang nicht verfügbar / finally Tive.

Andere Tipps

Nun, streng genommen, Java hat hat Block-scoped Variablendeklarationen; so ist dies ein Fehler:

void methodName() {
  for (int j = 0; j < 10; j++) {
    int i = j * 2;
  }
  System.out.println(i); // error
}

Da 'i' nicht für Block außerhalb der vorhanden sein.

Das Problem ist, dass Java nicht zulässt eine Variable mit dem gleichen Namen einer anderen Variablen zu erstellen, die in einem äußeren Block der gleichen Methode deklariert wurden. Wie andere Leute schon gesagt haben, angeblich wurde dies getan um Fehler zu vermeiden, die schwer zu identifizieren.

Weil es nicht ungewöhnlich, Schriftsteller dies absichtlich zu tun und dann völlig es vermasseln, indem zu vergessen, dass es nun zwei Variablen mit dem gleichen Namen sind. Sie verändern die innere Variablennamen, aber lassen Sie Code, der die Variable verwendet, die nun unintentially verwendet die zuvor beschattet Variable. Dies führt zu einem Programm, das immer noch kompiliert, aber führt buggily.

In ähnlicher Weise ist es nicht ungewöhnlich, dass versehentlich Variablen Schatten und das Verhalten des Programms zu ändern. Unwissentlich eine bestehende variable Abschattung kann so einfach wie unshadowing eine Variable, das Programm ändern, wie ich oben erwähnt.

Es gibt so wenig Nutzen Sie diese Schattenbildung zu ermöglichen, dass sie es als zu gefährlich ausgeschlossen. Im Ernst, nur sonst Ihre neue Variable etwas nennen, und das Problem weggeht.

Es zu Fehlern führt, die vor Ort schwer zu werden, denke ich. Es ist ähnlich wie in C #.

Pascal unterstützt dies nicht, da Sie Variablen über dem Funktionskörper erklären müssen.

Die zugrunde liegende Annahme in dieser Frage ist falsch.

Java funktioniert Block-Level-Umfang haben. Aber es hat auch eine Hierarchie von Umfang, weshalb Sie i im for Schleife verweisen können, aber nicht außerhalb der for-Schleife j.

public void methodName() {
  int i = 7;
  for (int j = 0; j < 10; j++) {
    i = j * 2;
  }

  //this would cause a compilation error!
  j++;
}

Ich kann nicht für das Leben von mir herauszufinden, warum Sie Scoping andere Art und Weise verhalten wollen. Es wäre unmöglich, zu bestimmen, welche i Sie Schleife bezieht wurden in der, und ich würde wetten Chancen 99,999% der Zeit, die Sie innerhalb der Methode zum i beziehen möchten sind.

ein weiterer Grund: Wenn diese Art der Variablendeklaration erlaubt wurden, würden die Leute wollen (müssen?), Einen Weg äußeren Block Variablen zuzugreifen. kann wie etwas sein „äußere“ Schlüsselwort hinzugefügt werden würde:

void methodName() {
    int i = 7;
    for (int j = 0; j < 10; j++) {
        int i = outer.i * 2;
        if(i > 10) {
            int i = outer.outer.i * 2 + outer.i;
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top