JAVA (структуры)
Модератор: Модераторы разделов
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
JAVA
Возник вопрос, на который я, уже довольно давно, не могу найти ответа: как java-программисты работают данными, которые в языках, типа C, могут быть представлены простой структурой?
Понятно, что можно, например, сложить некие переменные в класс, а потом уже каким либо методом достать их оттуда и превратить в непрерывный байтовый массив. Это, если формировать массив из переменных. А обратно как?
Есть ли что-либо в JAVA подобное указателям и структурам? Ведь, вряд ли, я первый, кто столкнулся с этой проблемой.
Понятно, что можно, например, сложить некие переменные в класс, а потом уже каким либо методом достать их оттуда и превратить в непрерывный байтовый массив. Это, если формировать массив из переменных. А обратно как?
Есть ли что-либо в JAVA подобное указателям и структурам? Ведь, вряд ли, я первый, кто столкнулся с этой проблемой.
Последний раз редактировалось devilr 26.06.2018 01:25, всего редактировалось 1 раз.
-
Kopilov
- Сообщения: 958
- ОС: [K]Ubuntu, Debian
Re: JAVA
Это называется «сериализация». Обратно — десериализация, соответственно. Если не нужна совместимость бинарного формата/протокола с другими языками и нет попыток выжать из Java производительности C/C++ — ObjectOutputStream и ObjectInputStream в помощь. Главное, чтобы в сериализуемом и десериализуемем классах совпадали все поля, а так же значения SerialVersionUID. Вот подстраиваться под существующие бинарные форматы уже сложнее.
-
Kopilov
- Сообщения: 958
- ОС: [K]Ubuntu, Debian
Re: JAVA
Что именно стало для Вас проблемой? Указателей нет, только ссылки. И их как-то всегда хватало… А чем именно классы хуже структур?
Коллега сейчас пишет программу для аналитики с узкоспециализированной областью применения, пытаясь обогнать по скорости топовые in-memory СУБД в своём use case. Он недавно мечтал о «C-подобных структурах для Java», но не для функционала, а для дальнейшей оптимизации уже оптимизированного кода.
-
Kopilov
- Сообщения: 958
- ОС: [K]Ubuntu, Debian
Re: JAVA
Правильнее даже, наверно, «А чем именно объекты хуже структур?» — если необходимостью на каждый чих писать классы — понимаю Вас, меня (и не только) это тоже одно время терзало. И это одна из причин, почему в нашем департаменте внедрили язык Ceylon: там есть синтаксический сахар для кортежей (туплов), очень близкий к классическим структурам по синтаксису и удобный для быстрого прототипирования ПО, но памяти жрущий ещё больше, чем классы и объекты.
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
Допустим, есть некая железяка, которая по некоторому интерфейсу шлёт пакеты, со структурой, подобной этой:
И их надо обработать, по возможности, быстро. В си-подобных языках я бы просто делал указатель, типа и обращался с полями данных легко и просто. А здесь... ну, можно конечно, брать из потока последовательно 2 байта, потом 1, потом снова 1, потом 2 и т.д. и складывать их в определённый класс. Но это долго и муторно, особенно, если структура завтра поменяется. Ошибок можно понаделать 100500 штук.
Вот и интересно, как другие программисты такое делают?
Код: Выделить всё
typedef struct HEADER
{
uint16_t prefix;
uint8_t addr;
uint8_t cmd;
uint16_t len;
uint8_t data[];
uint16_t sum16;
} header_t;Код: Выделить всё
HEADER *header = (HEADER *)data; Вот и интересно, как другие программисты такое делают?
-
serzh-z
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
Это понятно. Можно вообще на assembler.
Я больше про то, можно ли подобные "низкоуровневые" веши реализовать в рамках JAVA? Вдруг кто-то знает элегантное решение.
-
serzh-z
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
Не надо цепляться к словам. 
Часто не мы определяем среду и язык программирования.
Часто не мы определяем среду и язык программирования.
-
Bizdelnick
- Модератор
- Сообщения: 21513
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: JAVA
А вот ни фига это не легко и не просто даже в C. Железяка-то наверняка шлёт данные подряд, без выравнивания, а у Вас структура не packed. Не говоря о том, что Вы не учитываете порядок байт в пакете, так что такой код не будет переносимым.devilr писал(а): ↑26.06.2018 01:21Допустим, есть некая железяка, которая по некоторому интерфейсу шлёт пакеты, со структурой, подобной этой:И их надо обработать, по возможности, быстро. В си-подобных языках я бы просто делал указатель, типаКод: Выделить всё
typedef struct HEADER { uint16_t prefix; uint8_t addr; uint8_t cmd; uint16_t len; uint8_t data[]; uint16_t sum16; } header_t;и обращался с полями данных легко и просто. А здесь... ну, можно конечно, брать из потока последовательно 2 байта, потом 1, потом снова 1, потом 2 и т.д. и складывать их в определённый класс. Но это долго и муторно, особенно, если структура завтра поменяется. Ошибок можно понаделать 100500 штук.Код: Выделить всё
HEADER *header = (HEADER *)data;
Вот и интересно, как другие программисты такое делают?
Пишите правильно:
| в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Спасибо сказали:
-
Kopilov
- Сообщения: 958
- ОС: [K]Ubuntu, Debian
Re: JAVA
И кто определил за Вас, что драйвер (а у Вас получается именно драйвер для аппаратного обеспечения, не так ли?) надо писать именно на Java?
Впрочем, нет: лично сейчас делаю через Java кластеризацию математических расчётов над большими массивами данных (де факто, надо выпилить платный кластеризатор, идущий в комплекте с MATLAB, заставить ноды бегать на бесплатном Runtime и связать их самостоятельно). Подумав, что делать с сериализацией, решил использовать встроенную в RMI бинарную, т.к. перевод больших числовых матриц в текст и обратно — лишний расход не только вычислительных ресурсов, но и трафика.
Подстраиваться под существующие форматы, как я уже говорил, не так легко. Возможно, поможет Externalizable, но лично я этим не пользовался.
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
За выравнивание я просто не написал. Предполагая, что оно просто предполагается по умолчанию. Писал, чтобы не загромождать.Bizdelnick писал: ↑26.06.2018 10:46А вот ни фига это не легко и не просто даже в C. Железяка-то наверняка шлёт данные подряд, без выравнивания, а у Вас структура не packed. Не говоря о том, что Вы не учитываете порядок байт в пакете, так что такой код не будет переносимым.
То же, по поводу переносимости - оно просто часто не предполагается. Если надо, то endian можно тоже менять глобально.
Меня больше интересовало, можно ли это сделать красивее, хотя бы так, как в тот же C. Чтобы при изменении порядка данных в структуре, я менял только структуру, а не 100500 классов, использующих эту структуру.
-
serzh-z
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
-
yoshakar
- Сообщения: 259
- ОС: Debian Stretch
Re: JAVA
Позвольте спросить, а как вы умудрились написать сериализацию/десериализацию простой структуры так, что при измерении порядка передаваемых данных надо менять 100500 классов? В конце-концов, Java поддерживает ООП, а в ООП есть такая штука как инкапсуляция..
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: JAVA
Лично бы избегал таких задач в Java, не лучший язык для такого. Более того, даже сериализатор в POD-binary нормальный не написать, т.к.
ТруЪ Java путь, наверное, добавить аннотации для упорядочивания и другой информации.
, т.е. порядок никто не гарантирует.https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getFields-- писал(а):The elements in the returned array are not sorted and are not in any particular order
ТруЪ Java путь, наверное, добавить аннотации для упорядочивания и другой информации.
И тоже не получится, нет в Java unsigned типов. Придётся заводить int и в нём хранить значения от 0 до 65535. И контролировать по возможности.
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
Это да, но не всегда это возможно. Просто пример: андроид. И железяка, прикидывающаяся UARTом. И программист, знающий только JAVA.
По идее, если бы обработку потока данных от этой железки можно было бы просто написать на JAVA - было бы вообще прекрасно. Без всяких вставок, драйверов и прочих низкоуровневых штук.
Вообще, довольно странно, что в JAVA отказались от указателей и структур. Могли бы, хотя бы, объявить их "не безопасными" и оставить на откуп программисту.
Ну, на нет и суда нет.
Всем спасибо за участие!
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: JAVA
Даже если бы они были, их полезность была бы близка к нулевой из-за отсутствия unsigned типов (которые в структурах используются довольно часто). Так что придётся использовать ByteBuffer, там и Big/Little Endian задать можно.
-
Bizdelnick
- Модератор
- Сообщения: 21513
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: JAVA
NDK же есть. Можно сделать сишную либу с джавовскими биндингами.
Пишите правильно:
| в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
devilr
- Сообщения: 3697
- ОС: Mandriva => Gentoo (~amd64)
Re: JAVA
А можете подсказать, как? Или пример какой может где есть...Bizdelnick писал: ↑26.06.2018 19:51NDK же есть. Можно сделать сишную либу с джавовскими биндингами.