what is difference between mutable and immutable property of collection in kotlin - collections

I am upgrading corda from version 1 to version 3.1 in IntelliJ 2017 version. I am facing the issue with not nullable property of collection
private var valueContractTransactionsVO = Collection<ValueContractTransactionVO>
I am trying to create an object for a VO class of an empty collection type like I mentioned above, but it is throwing an error "Interface collection does not have constructors" and whenever I try to call that object, it is throwing error "Unresolved Reference".
Please help me to create an object for an empty collection without it being null.

If you need an empty read-only collection, you can call the emptyList function:
var valueContractTransactionsVO: Collection<ValueContractTransactionVO> = emptyList()
And if the type of valueContractTransactionsVO being a Collection is not significant for your case, you can specify the type argument of the emptyList function and let the compiler to infer its type to List<ValueContractTransactionVO>:
var valueContractTransactionsVO = emptyList<ValueContractTransactionVO>()

Related

No setter/field for isCreator found on class

When trying to access a Firestore database using Kotlin, the error quoted in the title is thrown. The fields of my model class exactly match the Firestore documents I'm trying to access. Why does Android Studio say there is no setter/field?
There is another field in the same class, which apparently works correctly, no error has been thrown. Even their type is the same, both are Boolean. The only difference is in their names, isCreator and admin (the working one).
The problem was with the properties' names. When a property's name starts with "is", one has to explicitly annotate the property's getter the following way:
#get:PropertyName("isCreator")
val isCreator: Boolean
If your property is mutable (aka var), you also have to annotate the setter;
#get:PropertyName("isCreator")
#set:PropertyName("isCreator")
var isCreator: Boolean

How to safely cast a reflected class in Kotlin

I need to dynamically load classes at runtime in Kotlin. I would like to check that they implement my interface, and if so, all green. Unfortunately, Kotlin's "smart casts" is failing me:
var className = "some.class.Name"
val unsafeClass = Class.forName(className).kotlin
require(unsafeClass.isSubclassOf(MyInterface::class)) {
"Class '$className' is not a MyInterface"
}
val safeClass = unsafeClass as KClass<MyInterface>
^^^^^^^^^^^^^^^^^^^^^^
Unchecked cast: KClass<out Any!> to KClass<MyInterface>
I'm clearly checking that the class implements the given interface. Can I re-phrase this code to avoid the warning?
I tried to test with is KClass<MyInterface> but I get a type erasure error (obviously, because the generic type information disappears at runtime.)
Edit: to clarify, my application needs to read class names "some.class.Name" at startup, during configuration; load those classes; check that they satisfy an interface; and store a Class or KClass reference for later. During runtime, it will use those references to create objects, using cls.createInstance() or such.
My question: is there any way to do so without getting unsafe cast warnings?
I can either get a warning at configuration time, when I cast the KClass<*> to KClass<MyInterface> (even though I required the class to be a subclass) but then I get no warning later on, because .createInstance() on a KClass<MyInterface> class reference returns a type-checked MyInterface instance.
Or, I can store the references as KClass<*>, without warnings at configuration time, but then I'll get the warning in the place where I create the instances, because I'll need to unsafe cast Object instances to MyInterface.
Is there any solution that will satisfy the compiler?
JVM and Kotlin implement generics only at the compiler level. One cannot see generic parameters of a generic class at runtime.
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
At runtime, there is no difference between Class<*> and Class<MyInterface>. These two are the same instance of Class type.
The warning that you have means that you have no information in the generic parameter at runtime, a compiler cannot validate it too, and it only can trust you
I do not see the reason cast the KClass to the KClass<MyInterface>. It is only necessary for an object, not it's class. Also, it probably can be simplified to use Class<*> instead, e.g:
val className = "some.class.Name"
val unsafeClass = Class.forName(className)
require(MyInterface::class.java.isAssignableFrom(unsafeClass)) {
"Class '$className' is not a MyInterface"
}
val safe = unsafeClass.newInstance() as MyInterface
This cast is not only unchecked, it's actually incorrect: because AMyInterfaceImpl::class has type KClass<AMyInterfaceImpl> and KClass is not covariant (for good reason), it does not have the type KClass<MyInterface>. You can see that from this code not compiling:
class AMyInterfaceImpl : MyInterface { ... }
val cls: KClass<MyInterface> = AMyInterfaceImpl::class
So if the cast could be checked, it would fail.
KClass<out MyInterface> would be correct, but I don't think the compiler will understand this and allow smart cast. It's just too rarely useful to teach the compiler.

MVVM-Light SimpleIoc: Can't create multiple instances dynamically

I am building an WPF application using the MVVM Light Toolkit and specifically SimpleIoc.
I have a parent viewmodel that dynamically creates child viewmodels. When doing this I am using "standard" dependency injection to pass a IConfigService as a parameter to the constructor. I want the IConfigService to be a unique instance for each child viewmodel. So I try this:
IConfigService service = SimpleIoc.Default.GetInstance<IConfigService>(key);
ChildViewModel vm = new ChildViewModel(service);
Where key is a unique identifier for each child viewmodel. According to the documentation of MVVM Light and SimpleIoc this GetInstance method:
...provides a way to get an instance of a given type corresponding to a given key. If no instance had been instantiated with this key before, a new instance will be created.
There is also a remark that the class must have been registered before, else it returns null. In my case it has been, in ViewModelLocator:
var configService = new ConfigService();
SimpleIoc.Default.Register<IConfigService>(() => configService);
However, the GetInstance call returns the same instance every time.
What am I doing wrong here?
You registered an already instantiated object.
SimpleIoc does not create its own instances with this overload. It always returns configService. Either you need to perform the instantiation within the lambda, because you are using a factory overload, or you can do this more easily by just passing the ConfigService type. SimpleIoc will take care of the instantiation itself.

Realm call setter

I'm using realm as database and kotlin as language.
I implemented my custom setter method for a property.
Does Realm call this setter somehow?
For example:
open class Human(): RealmObject()
{
open var Name: String = ""
set(value)
{
setName(value)
}
}
Now I also have a property changeDate and it would be nice if I can set the changeDate automatically in the setNameto new actual day.
But I can't do this if Realm calls this method also.
Thanks
I've tried this with Kotlin 1.1.1 and Realm 3.0.0, and it doesn't call the custom setter, it assigns the value in some other way (which means that it even works if your custom setter is empty, which is a bit unexpected).
Edit: Looked at the generated code and the debugger.
When you're using an object that's connected to Realm, it's an instance of a proxy class that's a subclass of the class that you're using in your code. When you're reading properties of this instance, the call to the getter goes down to native calls to access the stored value that's on disk, inside Realm.
Similarly, calling the setter eventually gets to native calls to set the appropriate values. This explains why the setter doesn't get called: Realm doesn't need to call the setter, because it doesn't load the values into memory eagerly, the proxy is just pointing into the real data in Realm, and whenever you read that value, it will read it from there.
As for how this relates to Kotlin code, the calls to the proxy's setter and getter that access the data inside Realm happen whenever you use the field keyword (for the most part).
var Name: String = ""
get() {
return field // this calls `String realmGet$Name()` on the proxy
}
set(value) {
field = value // this calls `void realmSet$Name(String value)` on the proxy
}

Passing reference types by ref - Flex/Actionscript

I know that in C# when you pass an object (non primitive) to a method the following is true:
A reference to the object is passed
Changes made to the object in the method are reflected outside of the method.
Also, you can pass a reference to a reference in C# e.g this.changeObject(ref myObject);, in which case:
Changes to the object and also to the ref are reflected outside of the method e.g. myObject = new new List(); would change the passed objects referred location.
My question:
Is this possible to do in Flex/Actionscript - can a ref keyword be used?
No, you cannot. ActionScript doesn't have a ref keyword or a similar (double pointer like) concept. You always pass object references to functions (except for primitives) and modifications are reflected back.

Resources