Defined 'subtype' is not available in generated Java API.
Consider the following schema:
package myschema;
struct MyTemplate<MY_TYPE>
{
MY_TYPE value;
};
subtype MyTemplate<int32> MyType;
When generating the API for Java, there is no class/type-identifier MyType available, for Python and C++ there is.
I expected that subtype defines something that has to be provided by the API regardless of the target language.
Java language does support any alternative to C++ typedef. Therefore subtypes in Java is resolved during API generation (resolved means that generated Java API uses always original type directly).
We might consider to use duplication or inheritance in the previous example but we will still have a problem for native types:
subtype uint32 U32;
Besides of that, subtype in Zserio means alias which allows writing the following schema:
struct Identifier
{
uint32 id;
};
subtype Identifier Parameter;
struct Consumer(Parameter parameter)
{
uint32 value;
function bool isIdZero()
{
return parameter.id == 0;
}
};
struct Holder
{
Identifier identifier;
Consumer(identifier) consumer1;
Parameter parameter;
Consumer(parameter) consumer2;
};
So, because Zserio language uses alias, we must find out the real alternative in Java to be able to generate working code.
Regarding problem with native/primitive types, we might think to use objects instead of them. In this case, we will be hit by significant memory and performance penalty. The fresh comparison of memory and performance between primitives and objects is available at https://www.baeldung.com/java-primitives-vs-objects.
The solution for classes (not for native/primitive types) could be if subtypes will be modeled by inheritance of original types and original types will be used everywhere instead of subtypes. Or maybe even better original types will define interface which will be implemented by all subtypes.
Note that even with interfaces the getters will still return only the interface, so that the following Java code will not compile:
someZserioObject.setMyField(new MySubtype(10)); // here it works since MySubtype will down-cast to MyBaseType
final MySubtype field = someZserioObject.getMyField(); // myField member will always be of type MyBaseType and thus the up-cast will not work automatically
The member cannot by of type MySubtype since it then wouldn't be possible to call setter with MyBaseType.