Java не правильно декомпилируется

Я разрабатываю для Android и компилирую с Gradle из Git, используя jitpack.io

Я пытаюсь использовать эту библиотеку из 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();
}

Буду признателен за любую помощь.

В настоящее время я не вижу причин, почему код выглядит иначе

Спасибо

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).

Другая интересная вещь заключается в том, что компилятор поставил groups.get(...).add(...) заявление внутри вашего для цикла. Если вы думаете о контракте for(initialisation; termination; increment) затем increment происходит на каждой итерации цикла. Таким образом, даже если вы написали свое утверждение внутри цикла, это тот же эффект. [Вероятно, для этого есть веская причина, я не гуру компилятора, поэтому не могу сказать наверняка].

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

    return groups.values();
}

Остальная часть кода в точности соответствует тому, что вы написали.

Другие вопросы по тегам