https://kotlinlang.org logo
j

jdiaz

03/05/2019, 11:23 AM
How would you instantiate a data class (probably with val) if you have the property names as string and the values with the correct type? I can't wrap my mind around it
d

diesieben07

03/05/2019, 11:58 AM
You'll have to use full reflection for this, but:
Without full reflection you'll have to use Java reflection, which has a way less useful API
j

jdiaz

03/05/2019, 11:59 AM
I like that callBy, but I still need to find the matching constructor as that's from KCallable
Works!
Just for future reference if anyone wants: https://pastebin.com/rHh6Y8DU
It still doesn't work with private data classes, I guess I'll have that constraint
d

DALDEI

04/30/2019, 11:37 AM
FYI I achieve this using a combination of kotlin-jackson module, the "--no-args' compiler extension, and a wild Imagination. Full code is too complex and case dependant, the concept is that Jackson (json parser/data mapper) can function as a pure type conversion (no 'json')) and with the no-args compiler extention (and a custom Annoation ) Jackson can contruct data classes with no defult values -- long eough to provide them in other means. For exmple you canprovide Map<String,Any> with the parameters (or with the right options set, MORE then 3enough -- aka thounds of entries if you want to say just read from a system wide config file) provide that as the 'source object,. and the desired class as the target (by generic parameter or by concrete class object) and call one of the methods that does tyhpe conversion such as DataMapper.convertValue( map , targetClass) --> voila -- jackson figures out how to find the construtors, and baring that uses the no-arg case and creates a temporarily 'invalid' object then proceeds to fill in the required members from the source until done returning a new full populated instance of the desired class.
Effeciency-wise -- not as good as if you knew exaclty what to do ,, but usefueness is high because you dont have to know very much at compile or runtime in your own code FYI: I have futher abused sanity by then impolementing a variant on Proxy via Bean Buddy which you can give a Interface or Abstract Class as the TARGET class, and a dynamicly generated kotlin data class is created matching properties of the interface, passed that to the above and I can create and populate on demand a concretei instance of a Interface with no concrete class objects in scope at compile time.
TO go one step further, you need the inteface , all thats used is the inspect list of property name/type/nullabilty/var-val .. If you provide those via some other way (say a map of Type Defs, for example as determined at runtime by the metadata from a JDBC Result set) --> out comes an object of a new (or cached/reused) concrete class with no base class with the 'signatuure' of a data class with all the supplied properties. From there you then can create instances of said class as you read each row of the results set using the first technique. End result -- > dynamic SQL/jDBC binding to dynamically created 'POJO's or 'Data Clasess' which behave nicely when given to code expecting to use reflection. Ex.amp.e a Vaadin Form or Grid which is auto generated and typed entirely by reflection of the row data objects -- (column headers, types, typed field editors etc) without having at compile time EITHER an interface or a concrete class.
41 Views