1

Android用に開発し、jitpack.ioを使用してgitからgradleでコンパイルしています

関数型プログラミングのためにgitからこのライブラリを使用しようとしています:

fj - Java 7 の関数型プログラミング

すべてがテストされているにもかかわらず、コードを実行してエラーが発生しました。

問題は GroupBy クラスにあります。

ソースコード:

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();
}

逆コンパイルされたコード:

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();
}

助けていただければ幸いです。

現在、コードが異なって見える理由はわかりません

ありがとう

4

1 に答える 1

1

簡単に言えば、Java がコンパイルされると情報が失われるということです。ただし、逆コンパイルされたコードは、作成したコードとまったく同じように機能します。

行ごとに見てみましょう...

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

これは同じですが、Groupクラスに完全な名前が付けられています。

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

ここでわかるように、変数名とすべての一般的な情報が失われています。Java のジェネリックは、コンパイラがエラーをチェックするためのヒントと考えることができます。コンパイラがコンパイルを完了すると、情報は破棄されます (通常)。

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

強化された for ループは、従来の for ループに置き換えられました。これは、バイトコードではそれらが同じであるためです (ただし、より賢い逆コンパイラがこれを理解し、ここで強化された for ループを記述している可能性があります)。

ここでもう 1 つ興味深い点は、コンパイラがgroups.get(...).add(...)ステートメントを for ループ内に配置したことです。for(initialisation; termination; increment)then のコントラクトについて考えると、incrementループの反復ごとに発生します。したがって、ループ内にステートメントを記述しても、同じ結果になります。[おそらく、このようにするのには十分な理由がありますが、私はコンパイラの第一人者ではないので、はっきりとは言えません]。

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

    return groups.values();
}

コードの残りの部分は、あなたが書いたものとほとんど同じです。

于 2016-06-07T17:27:42.760 に答える