Pull to refresh

Comments 18

Неплохо было бы добавить в статью сравнительные бенчмарки.

Без реализации всего функционала тут сравнивать нечего, имхо. Да и написать json парсер с хорошей производительностью - та ещё задача, тут нет смысла сравнивать даже

return "null";

Действительно, почему бы вместо чего-то подобного null'у не вернуть строку "null", ведь давно известно, что из-за этого не случится ничего плохого (нет, https://youtu.be/_c1am8NSx_s)

Это было бы валидно для toString (если toString'ом предлагается этот объект сериализовывать обратно в json, но тогда у всех остальных типов toString вернёт не валидный json), но для getValue это прямо совсем не подходящий вариант.

Поскольку данный парсер ожидает в качестве корневого элемента объект, а не массив

Валидный json может быть не только объектом или массивом, но и любым примитивным типом.

Да, тут взято подмножество валидного json. В RFC указано, что помимо объекта, валидным может быть любое значение (массив, строка, число, true, false, null). да и в статье написано, что API-возвращают json-массивы и парсер этого не умеет.

Добавил в конце, как сделать так, чтобы парсер обрабатывал правильно любое значение, являющееся JSON (но только ровно одно).

Вообще есть много вопросов, начиная с банальных, например, зачем считать в JsonArray count отдельно, хотя можно взять от листа, причём там судя по всему ошибка в setElements, полагаю, надо бы и счётчик обновить.

Заканчивая тем, насколько это вообще будет работать. Если цель была в том, чтобы потренироваться в написании статей — тогда понятно, тренируйтесь дальше. А так сыро, трудночитаемо, и не очень полезно

Тоже писал мини-парсер для своих нужд, но только он получился еще компактнее:
https://github.com/AlmazKo/microjson
Использую его, когда нужна работа с json без биндинга. В больших проектах, конечно лучше брать что-то типа Jackson'a

Ну, во-первых, у вас в методе экземпляра класса Json parseValue() Вы не проверяете литералы true, false, null, а сразу перематываете на нужное число символов, полагаясь на первую букву, хотя это может быть другим словом, на букву t, например, "topa", что сразу не соответствует JSON. Во-вторых, в методе parseObject не учитывается грамматически-правильная последовательность, в том смысле, что после чтения ключа (имени свойства) в строке может идти '}', что нарушает последовательность (ожидался символ ':'). Т.е. по строке "{ "dummy" }" вернётся пустой JSON-объект, а должно быть сообщение об ошибке "ожидался ':' а получили сразу '}'". (указали в описании репы fail-fast parser). Ссылка

Спасибо за фидбек, уже забыл про эти моменты, поправлю! Добавлю в тесты.
Надо соответствовать описанию :)

Под заголовком "Состояния парсера" было бы хорошо разместить схему (конечный автомат?) состояний парсера. Я, например, заглянул за общим принципом реализации, а не за деталями в коде, поэтому слегка разочарован.
P.S. И вообще, реализация в коде объектов - типов данных просится под кат.

Сразу видно - человеку нечем заняться. Мне бы столько свободного времени. Надеюсь, этот велосипед не попадёт ни в какой крупный проект, иначе команде не позавидуешь.

PS: Автотесты-то хоть есть? Или совсем всё плохо?

А разве не надо для массивов тоже использовать дженерики в этом случае? А то получается что в конечном итоге, получив из массива объект, нужно будет кастить его тип?

Т.е.

public class JsonArray extends JsonElement<List<JsonElement>>

нужно заменить на что-то типа

public class JsonArray<TT> extends JsonElement<List<JsonElement<TT>>>

Или нет?

В Вашем случае всё равно придётся кастить в тип, поскольку JsonObject по строковому ключу извлекает значение в виде JsonElement. Да и при обработке тоже. В стэке ведь могут быть массивы содержащие различные подтипы JsonElement.

Че то мне лень вникать, но почему объекты из массива по строковому ключу извлекаются?

А то, что в массиве могут содержаться объекты разных типов это по моему вообще нарушение сути понятия "массив".

Зачем вообще тогда тут городить огород с дженериками если конечному пользователю все равно кастить? Да еще и так опасно.

Да, понятие "массив" неккоректно здесь использовать. Правильное понятие - "список". Но само понятие тянется из того же RFC 8259 (везде указано "array").

По строкову ключу извлекается значение из объекта. Значение уже может быть массивом, или тем же объектом по типу.

А дженерик здесь для getValue() из JsonElement. Но Java не C#. В рантайме у нас всё стирается, и остаётся Object. Поэтому нельзя писать T a = new T(). А в C# можно, при условии, что параметр тип T имеет конструктор. Указывается через ограничение where T : new()

Sign up to leave a comment.

Articles