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();
}
Остальная часть кода в точности соответствует тому, что вы написали.