Sometimes lint produces false warnins if field is operated via bunch of annotations. For a common example:
#SerializedName("id") #Expose private Integer id;
field id is assigned only via gson.fromJson(). Such operation is invisible for lint, thus it throws warning variable id is never assigned
So I want to configure lint, in this particular case, to ignore checks if field is ever assigned, if it is annotated with #SearializedName (please dont suggest raw #SuppressWarnings("unused") which has to be set manualy for every field and will block checks, if field is ever used)
Gson serialises fields using reflection, which takes place at runtime. That UnusedAssignment inspection finds variables which meet any of the following criteria:
the variable never gets read after assignment
the value is always overwritten with another assignment before the next variable read
the variable initializer is redundant (for one of the above two reasons) - the variable is never used.
Your only option to get rid of warnings for this specific inspection is to suppress them, either by updating your lint.xml, or via #SuppressWarnings("unused"). If you really don't want to do either of those things, then it may be possible to write a custom Lint inspection that ignores fields with a #SerializedName annotation.
The disadvantage of this approach is if you want to use #SerializedName in a class that isn't serialised by Gson, you will no longer get a warning if a variable is unused. It is also much more complicated than adding #SuppressWarnings("unused") to the top of your GSON model classes.
Related
The following code shows up "Property must be initialized or be abstract" error.I understand that I can use lateinit in such cases but I wanted to know the reason behind the restriction .
class Student{
val s:String
}
In the case of a non-nullable property like in your example, the reason is necessity. Java implicitly gives member variables a value of null. In Kotlin, a non-nullable property cannot have a value of null, so you have to give it an instance of something to be the starting value.
But even if you declared it as nullable String?, Kotlin will require you to specify the starting value. Kotlin avoids making implicit assumptions about the intent of your code. Kotlin's design goals are to make code more readable and robust. The designers have done research on common causes of bugs in other languages, and have made Kotlin more restrictive in areas that have been frequent sources.
In kotlin, if we use a when block on an enum while exhausting all the enum values but without adding an else branch, we get this warning: "Enum argument can be null in Java, but exhaustive when contains no null branch".
Android Studio then suggest to add the suppress flag #Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA") either to the statement, function, class or file scope.
Is there any way to add this to the project scope ? Since my project is 100% Kotlin I don't need this warning and would like to disable it globally.
While using Room Persistence Library, I wonder why we have to explicitly specify the entities while creating a RoomDatabase as the entities are already annotated with #Entity annotation. I mean We could simply skip the entities attribute of the #Database annotation.
It's still useful. Sure we could remove it but:
Can't/convinent way to specify some the other things we can specify in that annotation as arguments in there.
It describes the intention, this is important. This means that other parts (tools/IDE) can check if this really is an Entity you are trying to fetch or if a mistake was made.
As a marker "interface", related to the previous point, but to simply communicate what it is and easily find them.
Tools/lib/frameworks might/probably need/want it as they can generate stuff/shadow classes/subclasses or such things. At least for analysis, related to first 1st and 2nd point as well.
For example see the EntityProcessor in the source for Room.
in my class extend ConstraintLayout. I have defined val-type variables in the class.
After running the program in the debug mode, I see that all the variables are zero.
Why is this going to happen?
When you define variables with initializers, the Kotlin compiler will generate a constructor which will execute all the initializers in sequence. Before the initializers are executed, the values of the corresponding fields will be 0, and this is the state that is shown on your screenshot.
For values such as IMEOPTIONS_ACTION_DONE, which seem to be constants, you shouldn't use regular class properties. Instead, you should put them into a companion object or on the top level of a file.
I cannot find it clearly documented anywhere if getters and setters are actually required for fields in a Realm Model. For example, the documentation at https://realm.io/docs/java/latest/api/io/realm/RealmObject.html says
The only restriction a RealmObject has is that fields are not allowed
to be final, transient' or volatile. Any method as well as public
fields are allowed. When providing custom constructors, a public
constructor with no arguments must be declared and be empty.
Fields annotated with Ignore don't have these restrictions and don't
require either a getter or setter.
Which seems to hint that it is required with getters and setters for non-ignored fields. Yet, the documentation at https://realm.io/docs/java/latest/#customizing-objects says
It is possible to use RealmObjects almost like POJOs. Extending from
RealmObject, you can let the fields be public, and use simple
assignments instead of setters and getter.
and then show the code for a Realm Model that does not have any getters and setters and instead have public fields we should use. Really? I thought Realm didn't even store any values in the actual fields, so reading and writing from them is probably a bad idea? I mean their debugging docs https://realm.io/docs/java/latest/#debugging state:
Unfortunately these values are wrong because the field values are not
used. Realm creates a proxy object behind the scenes and overrides the
getters and setters in order to access the persisted data in the Realm
So could someone please enlighten me? Can I skip getters and setters and just stick with public fields? Is there any thorough docs on this?
public fields work in most cases, and since Realm 2.0.0 they work even in constructors of RealmObjects (allowing "default values"), and work if you directly access the property.
For example,
SomeObject obj = results.get(i);
obj.blah = "Blahblah";
That works, because managed RealmObjects' field access are transformed by the Realm-Transformer into proxy getter/setter calls (in this case, into the realmSet$blah method).
This has been the case since 0.88.0, when Realm started being provided as a Gradle plugin.
However, a major limitation is that the proxy field access doesn't run in instrumentation tests, because the androidTestCompile scope does not run the transformer.