2013-05-23 28 views
15

Ich bin mit Eclipse mit dem PMD Plug-in (4.0.0.v20130510-1000) und viele dieser Verletzungen erhalten:PMD: DD/DU Anomalie

Found 'DD'-anomaly for variable 'freq' (lines '187'-'189').
Found 'DU'-anomaly for variable 'freq' (lines '189'-'333').

In this SO beantworten, heißt es, dass diese Anomalien die Zuordnung verwandt sind Werte, die nie gelesen werden. Aber ich habe die Verletzungen zum Beispiel in diesem Fall:

// here I get a DD anomaly 
double freq = 0; 
try { 
    // here I get a DU anomaly 
    freq = Double.parseDouble(getFrequencyTextField().getText()); 
} catch (final NumberFormatException e) { 
    Log.e(e.getMessage()); 
} 
if (freq < 10E6) doSomething(); 

Wenn ich die Initialisierung und fügen Sie eine freq = 0; Linie im catch Block zu entfernen, die DD Anomalie verschwindet, aber ich erhalte ein DIR Anomalie sowohl die Zuordnungen.

Jetzt meine Frage: Wie soll ich damit umgehen? Was wäre die bevorzugte Lösung von PMD? Und was genau versucht diese Regel zu verhindern (d. H. Warum ist es eine schlechte Praxis)?

Antwort

17
double freq; // (1) 
try { 
    // here I get a DU anomaly 
    freq = Double.parseDouble(getFrequencyTextField().getText()); 
} catch (final NumberFormatException e) { 
    Log.e(e.getMessage()); 
    freq = 0; // (2) 
} 
if (freq < 10E6) doSomething(); 

Das erste Problem ist, dass in der Catch die parseDouble Zuweisung nicht zu freq getan wird. Auf einer Ausnahme wäre Freq immer noch 0. Vielleicht flaggable. So geht es beim Zuweisen von freq inside catch.

Bei Zuweisung zu freq im catch, (2), würde die ursprüngliche Zuweisung (1) niemals gelesen werden, so dass nur eine Deklaration ausreicht.

Im Hinblick auf eine bessere Art:

try { 
    // here I get a DU anomaly 
    double freq = Double.parseDouble(getFrequencyTextField().getText()); 

    if (freq < 10E6) doSomething(); 
    ... 

} catch (final NumberFormatException e) { 
    Log.e(e.getMessage()); 
} 

Oder die Antwort von @JoachimSauer folgen, eine doppelte Umwandlung verwenden, die keine Ausnahme werfen. Die Protokollierung würde einen Grad der Ernsthaftigkeit gegenüber dem obigen Stil anzeigen. Das Einloggen in eine einfache Konvertierungsfunktion im Fehlerfall ist möglicherweise kein guter Stil: zu viel Protokollierung, ignorierte Protokollierung (?), Schwer zu reparieren.

+0

Danke für die Erklärung, das hat mir die Dinge aufgeräumt. Danke auch für den Vorschlag.Ich schätze immer Code-Korrekturen. (Deshalb habe ich angefangen PMD zu benutzen.) – brimborium

2

Sie können dieses Problem umgehen (und getrennten Bedenken etwas deutlicher) durch die Analyse in einem separaten Verfahren zu extrahieren:

double freq = parseDouble(getFrequencyTextField().getText()); 

// later in the class (or in a utility class): 

public static double parseDouble(final String input) { 
    try { 
    return Double.parseDouble(input); 
    } catch (final NumberFormatException e) { 
    Log.e(e.getMessage()); 
    return 0; 
    } 
} 

Und wenn Sie verschiedene Standardwerte haben, können Sie auch eine zwei hinzufügen könnte -argument Version: public static double parseDouble(final String input, final double defaultValue).

+0

Ich mag die Vorgabewert Idee. Ich denke, ich werde das tun. Obwohl ich in diesem Beispiel nur die nächste PMD-Verletzung erhalte: "Eine Methode sollte nur einen Ausgangspunkt haben, und das sollte die letzte Anweisung in der Methode sein". – brimborium

+0

@brimborium: Diese Warnung erzeugt eine hässliche semantische Schleife: Ich sehe keine (einfache) Lösung, um * beide * Warnungen gleichzeitig zu vermeiden. –

+0

Ja, ich bin geneigt, diese zweite Regel aus dem Regelsatz zu streichen. Obwohl ich verstehe, dass es Sinn macht. Es ist viel einfacher, die volle Bedeutung einer komplexen Methode zu verstehen, wenn es nur einen Ausgangspunkt gibt ... – brimborium