2009-12-28 4 views
9

Je reçois une classe anonyme à la compilation que je ne m'attendais pas. Code pertinent suit, puis une explication plus détaillée:Référence à Enum Public résultats dans la classe Anonyme

Intégralité de CircuitType.java:

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

De Auditor.java, lignes 3-9:

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

lignes De Auditor.java, 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; 
} 
[...] 

De Circuit.java, lignes 1-5:

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

Lorsque la commande

javac *.java 

est exécuté, une classe anonyme vérificateur 1.java $ est généré. De toute évidence, les fichiers sont placés côte à côte dans un répertoire de système de fichiers qui ne contient rien d'autre.

Lorsque les lignes 104-121 sont mises en commentaire, aucune classe anonyme n'est générée. J'ai d'abord pensé que c'était un problème de paquetage, donc mettez les trois classes dans un paquet, mais je ne savais pas assez sur les paquets pour le faire fonctionner. Si c'est vraiment un problème d'emballage, quelqu'un peut-il m'expliquer exactement comment les étiqueter? Je préférerais ne pas devoir les emballer si je n'ai pas à le faire.

La raison pour laquelle la classe anonyme est un problème, outre le fait que ces classes signifient généralement un problème d'espace de noms, est qu'elle casse mon Makefile que j'utilise pour la compilation automatique.

Mise à jour


Ci-joint une session de console qui, je l'espère faire la lumière sur ce mystère:

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

Malheureusement je ne peux pas aider avec le problème, mais +1 affichant une très question bien posée. –

+1

Ce n'est probablement pas la réponse que vous vouliez entendre, mais 'make 'n'est pas vraiment un outil approprié pour le développement de Java. Je recommande fortement d'utiliser 'ant' à la place. Au fur et à mesure que vous développez des applications plus complexes, vous aurez des classes anonymes partout et à juste titre. –

+0

Je serais intéressé de voir plus de Auditor.java. Sur la base de ce que vous avez déclaré ici, j'ai du mal à croire que Circuit.java soit le problème. – Shaun

Répondre

4

Je suis allé de l'avant et construit un petit projet contenant la source posté et juste assez de cadre autour d'elle pour le faire compiler. J'ai 3 fichiers de classe: Circuit.class, CircuitType.class et Auditor.class - comme prévu.

Tout cela sous Java 1.6. Mais comme d'autres l'ont indiqué, je pense que votre diagnostic du problème est éteint.

classes anonymes sont faciles à générer accidentellement: En règle générale une construction comme

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

va créer un, par exemple. Compte tenu de plus de votre code, les bons SO pourraient être en mesure de localiser votre erreur. Il peut être intéressant et instructif de désassembler vos fichiers de classe avec javap ou, mieux encore, un désassembleur Java "réel" comme JD.


Mise à jour

Ajouté le nouveau code de vérificateur à la mienne ... aucun changement. Pas de cours anonymes.

Votre code est bien sûr correct (dans la mesure où nous pouvons le voir) mais le design n'est pas très OO. Certaines personnes soulignent que vous devrez étendre vos déclarations de compteur et votre déclaration switch chaque fois qu'un nouveau type de circuit apparaît.

Vous n'utilisez pas non plus les «particularités» des énumérations. J'ai une version très simplifiée de votre méthode Auditor:

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

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

Mise à jour 2

J'ai trouvé votre sortie javap très éclairante. Voir mon commentaire ci-dessous.

Mes conclusions:

  1. Oui, apparemment votre Java impl utilise une classe anon pour le commutateur. Lame, mais légitime.
  2. Vous avez les options suivantes:
    • éliminons le switch
    • utiliser une implémentation Java différente
    • en direct avec la classe anonyme; fossé make et utiliser ant pour embrasser les classes anon et autres étrangetés de Java.

Puisque vous êtes seulement des problèmes en raison de la configuration de votre compilation non standard, je partirais avec la dernière solution et d'attaquer le problème.

+0

J'ai inclus plus de code de Auditor.java, selon votre demande. Le bloc de code de la ligne 104-121 est sûr du coupable, car la classe anonyme n'est pas générée lorsque ce bloc de code est mis en commentaire. Je crois que j'ai inclus tout ce qui concerne ce bloc de code. Si vous avez besoin de quelque chose d'autre, faites-le moi savoir. – Maarx

+0

Mise à jour de ma réponse pour répondre à vos mises à jour. –

+0

Mon esprit est soufflé. Deux fois. Il y a certainement une classe anonyme pour moi avec l'instruction switch, et il n'y a certainement pas de classe anonyme quand l'instruction switch est mise en commentaire. Lorsque vous avez dit que vous n'aviez toujours pas de classe anonyme, j'ai déplacé le code de mon environnement de développement UNIX vers une machine virtuelle Windows avec la dernière mise à jour du JDK et recompilée. Je reçois toujours une classe anonyme avec l'instruction switch, et aucune sans. – Maarx

Questions connexes