2016-06-07 8 views
1

Im für Android zu entwickeln und Kompilieren mit gradle von Git mit jitpack.ioJava nicht de-kompiliert richtig

Im Versuch, diese Bibliothek von git für funktionale Programmierung zu verwenden:

fj - functional programmming for Java 7

I hat den Code ausgeführt und Fehler bekommen, obwohl alles getestet wurde.

Das Problem ist in der Klasse GroupBy:

Quellcode:

public Collection<Group<S,T>> execute(Collection<T> collection){ 
    Hashtable<S, Group<S, T>> groups = new Hashtable<S, Group<S, T>>(); 

    for (T item: collection){ 
     S classification = grouper.select(item); 

     if (!groups.contains(classification)){ 
      groups.put(classification, new Group<S, T>(classification)); 
     } 
     groups.get(classification).add(item); 
    } 

    return groups.values(); 
} 

De-kompilierten Code:

public Collection<GroupBy.Group<S, T>> execute(Collection<T> collection) { 
    Hashtable groups = new Hashtable(); 

    Object item; 
    Object classification; 
    for(Iterator var3 = collection.iterator(); var3.hasNext(); ((GroupBy.Group)groups.get(classification)).add(item)) { 
     item = var3.next(); 
     classification = this.grouper.select(item); 
     if(!groups.contains(classification)) { 
      groups.put(classification, new GroupBy.Group(classification)); 
     } 
    } 

    return groups.values(); 
} 

ich Hilfe schätzen würde.

Derzeit nicht ich keinen Grund, warum der Code anders aussehen

Dank

+1

Dekompilierern werden tatsächlich nicht zur exakten Quelle dekompilieren. da es nur den Byte-Code sieht, wird es versuchen, zu etwas zu dekompilieren, das so nahe wie möglich an der Quelle ist, aber Sie werden nie den genauen Code erhalten, den Sie vorher hatten, obwohl es das gleiche tun sollte –

+0

OK. Ich habe eine Antwort ... 1. Der de-kompilierte Code tut genau das Gleiche. Es ist nur eine Transformation von Code und Optimierung durch den Compiler 2.Der Fehler, den ich hatte, war, weil ich "contains" anstelle von "containKey" verwendet habe – Gur

Antwort

1

Die kurze Antwort ist, dass, wenn Java eingehalten Informationen verloren gehen. Der dekompilierte Code funktioniert jedoch genauso wie der Code, den Sie geschrieben haben.

Schauen wir uns Zeile für Zeile ...

public Collection<GroupBy.Group<S, T>> execute(Collection<T> collection) { 

Dies ist die gleiche, obwohl es die Group Klasse seinen vollständigen Namen gegeben hat.

Hashtable groups = new Hashtable(); 
    Object item; 
    Object classification; 

Wie Sie hier sehen können, sind die Variablennamen und alle generischen Informationen verloren. Generics in Java kann man sich als Hinweis auf den Compiler vorstellen, um nach Fehlern zu suchen. Sobald der Compiler das Kompilieren beendet hat, wird die Information weggeworfen (allgemein).

for(
     Iterator var3 = collection.iterator(); 
     var3.hasNext();       
     ((GroupBy.Group)groups.get(classification)).add(item) 
    ) { 

Die for-Schleife verstärkt wird durch eine klassische for-Schleife ersetzt. Dies liegt daran, dass sie im Bytecode dasselbe sind (obwohl ein klügerer Decompiler dies herausgefunden haben könnte und hier eine erweiterte for-Schleife geschrieben hat).

Die andere interessante Sache hier ist, dass der Compiler die groups.get(...).add(...) Anweisung innerhalb Ihrer for-Schleife gesetzt hat. Wenn Sie an den Vertrag von for(initialisation; termination; increment) denken, dann passiert increment bei jeder Schleifeniteration. Obwohl Sie Ihre Anweisung innerhalb der Schleife geschrieben haben, ist dies der gleiche Effekt. [Es gibt wahrscheinlich einen guten Grund, dies auf diese Weise zu tun, ich bin kein Compiler Guru, also kann ich nicht mit Sicherheit sagen].

 item = var3.next(); 
     classification = this.grouper.select(item); 
     if(!groups.contains(classification)) { 
      groups.put(classification, new GroupBy.Group(classification)); 
     } 
    } 

    return groups.values(); 
} 

Der Rest des Codes ist ziemlich genau das, was Sie geschrieben haben.