Kotlin reflection on object instance - reflection

I've been trying some stuff from kotlin.reflection during my project, and got stuck on something what occurs to me as hard to understand, I have declared object as follows:
object WebsiteMapping
{
const val ADMIN = "/admin"
}
once I call:
Arrays
.stream(WebsiteMapping::class.java.declaredFields)
.forEach { field -> println(field.type) }
what I get is:
class java.lang.String
class mapping.WebsiteMapping
When I looked a little bit into what is behind declaredFields invocation I grasped why it works as it is, but is there any convenient way of taking only declared consts within that object without getting also root of the whole structure?

The field with the type class mapping.WebsiteMapping is, basically, not the root of the structure but a special field generated in the object type that holds the reference to the singleton object.
In Kotlin, this field is named INSTANCE by convention. You can therefore filter the fields that you get from the class as follows:
WebsiteMapping::class.java.declaredFields
.filter { it.name != "INSTANCE" }
.forEach { println(it.type) }
Another solution is to switch from java.reflect.* to the Kotlin reflection API kotlin.reflect (needs a dependency on the kotlin-reflect module), which automatically filters the property:
WebsiteMapping::class.memberProperties
.forEach { println(it.returnType) }

Related

Dart - Casting List<SuperType> to List<SubType> using generics

I am new to Flutter and Dart, coming from native Android.
Android has a very nice database abstraction architecture called the Room Persistence Library. As far as I am aware, no such database abstraction architecture exists for Flutter using the MVVM / MVC design patterns.
My solution was to create a Dart version of it myself. I got it pretty much done after a few headaches, but I cannot seem to get LiveData to work properly using generics.
I set up my class like this:
class LiveData<T> {
...
}
Now when I want to return some data, it can either be an Object or List<Object>. I found a neat hack for differentiating the two from T:
...
// Parse response
// This checks if the type is an instance of a single entity or a list.
if (entity is T) {
cachedData = rawData.isEmpty ? null : entity.fromMap(rawData.first) as T;
} else {
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;
}
...
The problem lies in the second block:
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;
With the error:
- Unhandled Exception: type 'List<Entity>' is not a subtype of type 'List<Vehicle>' in type cast
The question then becomes: How can I cast Entity to Vehicle when I do not have access to the Vehicle class. Only an instance of it is assigned to an Entity entity variable.
Here's a snippet to demonstrate my access to Vehicle:
final Entity entity;
...assign Vehicle instance to entity...
print(entity is Vehicle) // True
I've tried using .runtimeType to no avail. I have also thought about splitting LiveData into two classes, the second one being LiveDataList. Although this seems to be the easiest solution to not bug the code- it would bug me (bad pun is intentional) and break the otherwise pretty direct port of Room.
As a temporary solution, I have abstracted out the build logic into a generic function to be passed to the LiveData in the constructor.
final T Function(List<Map<String, dynamic>> rawData) builder;
And now I call that instead of the previous code to build the cachedData.
// Parse response
cachedData = builder(rawData);
With the constructor for the LiveData<List<Vehicle>> called when accessing all vehicles in the Dao<Vehicle> being:
class VehicleDao implements Dao<Vehicle> {
...
static LiveData<List<Vehicle>> get() {
return LiveData<List<Vehicle>>(
...
(rawData) => rawData.map((e) => Vehicle.fromMap(e)).toList(),
...
);
}
}
In Dart (and indeed in many languages) generics screws with the concept of inheritance. You would think that if Bar inherits from Foo, that List<Bar> would also be castable to List<Foo>.
This is not actually going to be the case because of how generics work. When you have a generic class, every time you use that class with a different type, that type is treated as a completely separate class. This is because when the compiler compiles those types, class MyGenericType<Foo> extends BaseClass and class MyGenericType<Bar> extends BaseClass are basically converted to something like class MyGenericType_Foo extends BaseClass and class MyGenericType_Bar extends BaseClass.
Do you see the problem? MyGenericType_Foo and MyGenericType_Bar are not descendants of one another. They are siblings of each other, both extending from BaseClass. This is why when you try to convert a List<Entity> to List<Vehicle>, the cast doesn't work because they are sibling types, not a supertype and subtype.
With all this being said, while you cannot directly cast one generic type to another based on the relationship of the generic type parameter, in the case of List there is a way to convert one List type to another: the cast method.
List<Entity> entityList = <Entity>[...];
List<Vehicle> vehicleList = entityList.cast<Vehicle>(); // This cast will work
One thing to note though, if you are casting from a supertype generic to a sub-type generic and not all the elements of the list are that new type, this cast will throw an error.

Access Kotlin Delegate Type without an Instance

I have read Access property delegate in Kotlin which is about accessing a delegate from an instance. One can use KProperty::getDelegate since Kotlin 1.1, however this will return the instance of the delegate and therefore needs an instance of the class first.
Now I want to get the type of the delegate without having an instance of the class. Consider a library with a custom delegate type CustomDelegate that want's to get all properties of a class that are delegated to an instance of CustomDelegate:
class Example
{
var nonDelegatedProperty = "I don't care about this property"
var delegatedProperty1 by lazy { "I don't care about this too" }
var delegatedProperty2 by CustomDelegate("I care about this one")
}
How can I, given I have KClass<Example>, but not an instance of Example, get all properties delegated to CustomDelegate?
How can I, given I have KClass<Example>, but not an instance of
Example, get all properties delegated to CustomDelegate?
You can do it in two ways depending on your needs.
First of all, you have to include the kotlin-reflect dependency in your build.gradle file:
compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51"
In my opinion, you should use the first solution if you can, because it's the most clear and optimized one. The second solution instead, can handle one case that the first solution can't.
First
You can loop an the declared properties and check if the type of the property or the type of the delegate is CustomDelegate.
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// If the type of field is CustomDelegate or the delegate is an instance of CustomDelegate,
// it will return true.
CustomDelegate::class.java == property.javaField?.type
}
There's only one problem with this solution, you will get also the fields with type CustomDelegate, so, given this example:
class Example {
var nonDelegatedProperty = "I don't care about this property"
val delegatedProperty1 by lazy { "I don't care about this too" }
val delegatedProperty2 by CustomDelegate("I care about this one")
val customDelegate = CustomDelegate("jdo")
}
You will get delegatedProperty2 and customDelegate. If you want to get only delegatedProperty2, I found an horrible solution that you can use if you need to manage this case.
Second
If you check the source code of KPropertyImpl, you can see how a delegation is implemented. So, you can do something like this:
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// You must check in all superclasses till you find the right method.
property::class.allSuperclasses.find {
val computeField = try {
// Find the protected method "computeDelegateField".
it.declaredFunctions.find { it.name == "computeDelegateField" } ?: return#find false
} catch (t: Throwable) {
// Catch KotlinReflectionInternalError.
return#find false
}
// Get the delegate or null if the delegate is not present.
val delegateField = computeField.call(property) as? Field
// If the delegate was null or the type is different from CustomDelegate, it will return false.
CustomDelegate::class.java == delegateField?.type
} != null
}
In this case, you will get only delegatedProperty2 as result.

Jackson custom deserializer module to abstract class

I have a big set of classes (like more that 100) and they are all extend from some abstract class, let's call it ParentClass. Let's call child classes ChildA,ChildB, etc. How can I register custom deserializer for all children and get class type inside my Deserializer?
I tried:
module.addDeserializer(ParentClass.class, new MyObjectDeserializer());
but it does not work.
I want to skip doing (what is working):
module.addDeserializer(ChildA.class, new MyObjectDeserializer(ChildA.class));
module.addDeserializer(ChildB.class, new MyObjectDeserializer(ChildB.class));
module.addDeserializer(ChildC.class, new MyObjectDeserializer(ChildC.class));
//etc......
Class type should be known, as I am use Jackson for spring #RequestBody method, what have defined class name there.
Any ideas how this can be done?
As far as I know, I don't think there is a mechanism in jackson that will address your exact needs.
However, there are a couple alternatives you can try.
Deserializing polymorphic types with Jackson describes one such alternative, however, you would still need to explicitly define all of the supported subtypes.
Another alternative that would not require you to explicitly define deserialization relationships would be to change your class hierarchy from one of inheritance to that of a container.
For example, converting your abstract parent class to a container like so:
public class DataContainer<T> {
String commonString;
Integer commonInteger;
T subData;
}
Would allow you to simply define in your controller input function as
public String controllerFunction(DataContainer<ClassA> classA);
without a need to define all these subclass deserializations.
Late to the party but I had a similar problem which I solved by registering a custom Deserializers to my SimpleModule. The code is in Kotlin but it should be easy to port it to Java.
The class itself:
class UseBaseClassSimpleDeserializers(
private val baseClass: Class<*>,
private val baseClassDeserializer: JsonDeserializer<*>
) : SimpleDeserializers() {
#Throws(JsonMappingException::class)
override fun findBeanDeserializer(
type: JavaType?,
config: DeserializationConfig?,
beanDesc: BeanDescription?
): JsonDeserializer<*>? {
val beanDeserializer = super.findBeanDeserializer(type, config, beanDesc)
return if (beanDeserializer == null && baseClass.isAssignableFrom(type!!.rawClass)) {
baseClassDeserializer
} else {
beanDeserializer
}
}
}
How to register the custom Deserializers class to a SimpleModule:
val simpleModule = SimpleModule()
simpleModule.setDeserializers(UseBaseClassSimpleDeserializers(ParentClass::class.java, ParentClassDeserializer()))

How to check if a variable exists in flex

In flex, how to check if a variable exists? I have tried using
if (this['some_variable'] != undefined) {
//do something
}
There is a run time error saying the property some_variable does not exists. I have checked with null instead of undefined, still the same error.
please help.
[EDIT]
Based on the replies I have used this.hasOwnProperty('variable_name'). I found that its returning true if variable_name is a public but false if its private/protected. How to check for a private variable?
There are two ways for that:
if ("some_variable" in this) {
//do something
}
It uses in operator.
And:
if (this.hasOwnProperty("some_variable")) {
//do something
}
See documentation about hasOwnProperty().
What about getting information about private/protected properties the situation is that you can't get this info with the current state of Flash Player. The only possible way, I suppose, is some kind of runtime bytecode manipulation. But as far as I know nobody implemented it yet.
But I have a question about getting info about private/protected properties: for what purpose you need it? The nature of these properties/methods is you can't call them. Even if you know about their existence.
You can use
if (this. hasOwnProperty("some_variable")) {
//access the variable inside
}
if (this.hasOwnProperty('some_variable')) DO_IT_!()
Explanation:
this['some_variable'] tries to evaluate the value of the instance property some_variable. If there is no such a property, you will get this error.
To test if a property exists for a particular object use hasOwnProperty or wrap your condition in a try/catch block or use if ('some_variable' in this).
Usually you create an object property in a class file:
public class MyClass {
public var myProperty : String = "ich bin hier";
}
Then you refer to that property within the class:
trace (myProperty);
trace (this.myProperty);
Using the array syntax [] is also possible but will throw the error if the property is not defined.
trace (this['myProperty']);
And finally! If you declare your class to be dynamic you might use the array syntax even if the property does not exist.
public dynamic class MyClass {
public function MyClass() {
trace (this["never_declared_property"]);
}
}

Pass a C++/CLI wrapper of a native type to another C++/CLI assembly

Suppose I have the following simple wrapper of a NativeClassInstance.
public ref class Wrapper
{
private:
NativeClass *_wrapped;
public:
Renderer()
{
_wrapped = new NativeClass();
}
~Renderer()
{
delete _wrapped;
}
operator NativeClass*()
{
return _wrapped;
}
}
Now, I want to create an instance of Wrapper from C# with Wrapper wrapper = new Wrapper() and use it in another native functionalities wrapper that resides in another assembly with Helper.Foo(wrapper) (nothing strange having other functionalities not directly related to the wrapped classes in another assembly, IMO):
// Utilities is in another Assembly
public ref class Helper
{
public:
static Foo(Wrapper ^wrapper)
{
// Do something in native code with wrapper->_wrapped
}
}
The results with the implicit user conversion is:
candidate function(s) not accessible
If I make _wrapped public it is:
cannot access private member declared in class ...
Now, I've learnt that native type visibility is private outside of the assembly. So, how I'm supposed to use the wrapped entity in native code outside the assembly it's defined? I've read of make_public but you can't use with template types so it seems very limiting in the general case. Am I missing something? Is there a more correct solution?
I haven't been able to successfully expose native types using make_public, however a solution I have used is to put NativeClass in its own native DLL and then a) reference the native DLL from both assemblies; and b) pass the pointer to the native class around as an IntPtr.
Under the above scenario, instead of having an operator NativeClass* you might use a property such as
property IntPtr WrappedObject {
IntPtr get() { return IntPtr(_wrapped); }
}
You then retrieve NativeObject in you helper assembly by
static void Foo(Wrapper ^wrapper)
{
NativeObject *_wrapped
= static_cast<NativeObject*>(wrapper->WrappedObject.ToPointer());
// ... do something ...
}
If you use make_public, your solution of making _wrapped public should work (it would obviously be best to make a public accessor instead). Regarding your comment "I've read of make_public but you can't use with template types so it seems very limiting in the general case." I agree--read here for the workaround I used:
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b43cca63-b0bf-451e-b8fe-74e9c618b8c4/
More related info:
Best workaround for compiler error C2158: make_public does not support native template types
Good luck!

Resources