2009-12-28 10 views
9

Ich bekomme eine anonyme Klasse zur Kompilierzeit, die ich nicht erwarte. Relevante Code folgt, dann eine ausführlichere Erklärung:Verweis auf Public Enum Ergebnisse in anonyme Klasse

Entirety von CircuitType.java:

public enum CircuitType { V110A20, V110A30, V208A20, V208A30 } 

Von Auditor.java, Linien 3-9:

public class Auditor { 
    private String[] fileNames; 
    private int numV110A20; 
    private int numV110A30; 
    private int numV208A20; 
    private int numV208A30; 

Von Auditor.java, Linien 104-121:

[...] 
switch (newCircuit.getType()) { 
    case V110A20: 
     this.numV110A20++; 
     break; 
    case V110A30: 
     this.numV110A30++; 
     break; 
    case V208A20: 
     this.numV208A20++; 
     break; 
    case V208A30: 
     this.numV208A30++; 
     break; 
    default: 
     System.err.println("An Error Has Occured."); 
     System.exit(-1); 
     break; 
} 
[...] 

Von Circuit.java, Zeilen 1-5:

public class Circuit { 
    private CircuitType myType; 
    public CircuitType getType() { 
     return this.myType; 
    } 
[...] 

Wenn der Befehl

javac *.java 

ausgeführt wird, wird eine anonyme Klasse Auditor $ 1.java erzeugt. Die Dateien sitzen offensichtlich nebeneinander in einem Dateisystemverzeichnis, das nichts anderes enthält.

Wenn die Zeilen 104-121 auskommentiert sind, wird keine anonyme Klasse generiert.

Zuerst dachte ich, es war ein Paket-Problem, also legte die drei Klassen in ein Paket, aber ich wusste nicht genug über Pakete, um es zum Laufen zu bringen. Wenn es wirklich ein Paketproblem ist, kann mir jemand genau durchgehen, wie man sie beschriftet? Ich möchte sie lieber nicht verpacken, wenn es nicht nötig ist.

Der Grund für die anonyme Klasse ist neben der Tatsache, dass solche Klassen normalerweise ein Namespace-Problem darstellen, dass sie mein Makefile für die automatische Kompilierung zerstört.

aktualisieren


Beigefügt ist eine Konsolensitzung, die ich hoffe, dieses Geheimnis beleuchten kann:

% javap 'Auditor$1' 
Compiled from "Auditor.java" 
class Auditor$1 extends java.lang.Object{ 
    static final int[] $SwitchMap$CircuitType; 
    static {}; 
} 
+1

Leider kann ich nicht mit dem Problem, sondern ein Posting eine sehr helfen gut gestellte Frage. –

+1

Dies ist wahrscheinlich nicht die Antwort, die Sie hören wollten, aber 'make' ist nicht wirklich ein geeignetes Werkzeug für die Java-Entwicklung. Ich empfehle dringend, stattdessen "ant" zu verwenden. Wenn Sie komplexere Anwendungen entwickeln, werden Sie anonyme Klassen überall und zu Recht haben. –

+0

würde mich interessieren, mehr von Auditor.java zu sehen. Basierend auf dem, was Sie hier gesagt haben, fällt es mir schwer zu glauben, dass Circuit.java das Problem ist. – Shaun

Antwort

4

ich weiter gegangen und baute ein kleines Projekt die Quelle enthält, die Sie gepostet und gerade genug Framework um es zu kompilieren. Ich habe 3 Klassen-Dateien: Circuit.class, CircuitType.class und Auditor.class - wie erwartet.

All dies unter Java 1.6. Aber wie andere angedeutet haben, denke ich, dass Ihre Diagnose des Problems aus ist.

Anonyme Klassen sind einfach zufällig zu erzeugen: In der Regel ein Konstrukt wie

Circuit myCircuit = new Circuit() { 
    public CircuitType getCircuitType() { 
     return XXX; 
    } 
} 

wird man schaffen, zum Beispiel. Wenn Sie mehr von Ihrem Code haben, können die guten SO-Leute vielleicht Ihren Fehler genau lokalisieren.

Es könnte interessant und lehrreich sein, Ihre Klassendateien mit javap oder besser noch einem "echten" Java-Disassembler wie JD zu zerlegen.


aktualisieren

Hinzugefügt Ihren neuen Auditor-Code zu mir ... keine Änderung. Keine anonymen Kurse

Ihr Code ist natürlich korrekt (soweit wir es sehen können), aber das Design ist nicht sehr OO. Einige Leute würden darauf hinweisen, dass Sie Ihre Zählerdeklarationen und Ihre switch-Anweisung jedes Mal erweitern müssen, wenn ein neuer Schaltungstyp angezeigt wird.

Sie nutzen auch nicht die "besonderen Eigenschaften" von enums. Ich habe eine sehr vereinfachte Version Ihrer Auditor Methode:

private int[] counters = new int[CircuitType.values().length]; 

    public void tallySomething() { 
     Circuit newCircuit = new Circuit(); 
     counters[newCircuit.getType().ordinal()]++; 
    } 

aktualisieren 2

ich Ihre javap Ausgang ziemlich Beleuchtung gefunden. Siehe meinen Kommentar unten.

Meine Schlussfolgerungen:

  1. Ja, anscheinend Ihr Java impl für den Schalter eine Anon-Klasse verwendet. Lahm, aber legitim.
  2. Sie haben folgende Möglichkeiten:
    • beseitigen die switch
    • eine andere Java-Implementierung verwenden
    • mit der anonymen Klasse leben; Graben Sie make und verwenden Sie ant, um die Anon-Klassen und andere Besonderheiten von Java zu umarmen.

Da sind Sie nur Probleme mit wegen Ihres Nicht-Standard-Compilation-Setup, würde ich mit der letzten Lösung gehen und das Problem dort angreifen.

+0

Ich habe mehr Code von Auditor.java, je nach Ihrer Anfrage. Der Code-Block der Zeile 104-121 ist der Täter, da die anonyme Klasse nicht generiert wird, wenn dieser Code-Block auskommentiert ist. Ich glaube, ich habe alles relevante zu diesem Codeblock hinzugefügt. Wenn Sie noch etwas brauchen, lassen Sie es mich wissen. – Maarx

+0

Meine Antwort wurde aktualisiert, um auf Ihre Aktualisierungen zu antworten. –

+0

Mein Kopf ist durchgebrannt. Zweimal. Es gibt definitiv eine anonyme Klasse für mich mit der switch-Anweisung, und es gibt definitiv keine anonyme Klasse, wenn die switch-Anweisung auskommentiert ist. Als Sie sagten, dass Sie immer noch keine anonyme Klasse erhalten haben, habe ich den Code von meiner UNIX-Entwicklungsumgebung auf eine Windows-VM mit dem neuesten JDK-Update verschoben und neu kompiliert. Ich bekomme immer noch eine anonyme Klasse mit der switch-Anweisung und keine ohne. – Maarx

Verwandte Themen