print `this` variable in android - android

sometimes printf("%p", this) helps to see different instances.
What's the equivalent of that in android?
(to print out address of this variable or something unique(it may not be address) to the instance)
It seems I can new interface like OnTouchListener then, how do I print something to differentiate the different instances of them?

Something like this should do it:
android.util.Log.i("Instance", "This is: " + this);
By default, the toString implementation of Object will print the class type plus a hash code which can be considered somewhat equivalent to the this pointer in C++.
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character '#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
If an object provides a different implementation of toString(), like for instance String does, then you can use the above canonical implementation of the base toString() method to get the same results.

To get something distinct to the instance, you should use System.identityHashCode(this). It returns what the default implementation of .hashCode() in Object returns (which may have been overridden in subclasses, so that's why you shouldn't use .hashCode() directly), which, according to the documentation, is "As much as is reasonably practical" distinct for distinct objects.

Related

Kotlin Serialisation with Enum (kotlinx.serialisation library)

I am using kotlinx.serialisation and had a question.
I have JSON like this:
{
"state": "bad"
}
state can return bad|good|near_good
My State data class looks like this:
#Serializable
internal enum class State {
#SerialName("good") GOOD,
#SerialName("bad") BAD,
#SerialName("near_good") NEAR_GOOD
}
Is it possible to have the enum names remain all caps like this, while parsing the json value that is returned?
Right now when I test this, the parsed json data returns as GOOD|BAD|NEAR_GOOD, because the enum name is uppercase.
Hopefully the question makes sense.
Appreciate any answers.
EDIT (Updated for clarity)
Right now I have a test that checks:
assert(state.name == "bad")
This fails because with the way I mentioned it above (#SerialName("bad") BAD), the state.name is equal to 'BAD'.
I want the enum name to be uppercase, as per enum naming convention, but I want the value to be lowercase as per the JSON.
I can fix the failing test by changing it to be
#SerialName("bad") bad
I'm not sure if it is possible or maybe I am doing something in the wrong way, but I hope this clarifies.
Thanks!
I guess the problem is your test. It's not very robust to check for string equality. You have powerful compile-time guarantees with enums, so I would suggest to just compare enum values, not strings:
assert(state == State.BAD)
If you're trying to test the serial name of the enum value, then... don't? That's the job of Kotlinx Serialization's tests to verify that the annotations work correctly.
name is the wrong property to use for this purpose. It is documented as:
Returns the name of this enum constant, exactly as declared in its enum declaration.
What you could possibly do instead is to define a property (and, if you like, toString) for your enum class as follows:
val serialName =
declaringJavaClass.getField(name)
.getAnnotation(SerialName::class.java)
.value
// optionally set toString
override fun toString() = serialName
And then you can print it like this: println(state.serialName)
Or like this: println(state)
But the real question is:
Why do you want to do that?
The whole point of the SerialName name annotation is to parse the serialized value to your enum variable, and to encode your enum variable to the serialized value. The value of your enum variable itself is independent from the serialized value and remains an object (State.BAD etc) rather than a string.

Initialising map with an existing map in kotlin

I start with one map myInitialMap. i would like to create another map myNewMap that is initialised with myInitialMap.
val myInitialMap = mapOf<String, Int>("one" to 1, "two" to 2)
val myNewMap = mapOf(myInitialMap)
I get error:
Type mismatch.
Required: Pair<TypeVariable(K), TypeVariable(V)>
Found: Map<String, Int>
How can I initialise myNewMap with myInitialMap?
You can use myInitialMap.toList().toMutableStateMap().
The ...Of() functions in Kotlin all follow the convention of taking individual entries as varargs, which is why mapOf(myInitialMap) doesn't, and shouldn't, work. Since these functions use the arguments to determine the generic types, the list/set versions could not possibly support also having overloads that accept an Iterable parameter with all the entries to include, because you might actually want a list of Iterables (2D collection). For consistency, mapOf must behave the same.
Function naming/behavior conventions:
...Of(): A function taking a vararg parameter of all the individual values to put in the collection. The argument type can be used for the compiler to infer the generic type(s) of the collection.
.to...Map/Set/List(): An extension function that creates a shallow copy or new type of collection from the entries of the collection it is called on.
.as...(): An extension function that wraps the original object in another one. For example, asIterable() or asSequence() will return those types, but they will read from the original object. They are not copies.

I can't pass the argument while using higher order function

Here you can see that I can't pass that string parameter
I somehow learned how to pass a method in the same class but, when I want to call it from another class, I can't pass the arguments.
Several issues here:
the introduceMyself method accepts a higher-order function, but in its usage it seems that you don't want the method itself, but its result. I'd suggest replacing the getName parameter with name parameter and convert it to a regular string which will be provided externally by an invocation of said method.
In line 6, you have a syntax error. Since you're using an instance - person, you can replace the :: with a . like so: person.myNameIs("michael"). It's not working because :: passes the method itself, which you don't really want. Again, your code implies that you need to pass the result of the method and not the method itself.
Finally, you can pass higher order functions, but you can't pass them "with an argument". You can do one of 3 things:
Invoke the HOF locally and pass the result of the invocation
Pass the HOF and the argument and invoke them wherever it is you need to.
Pass the HOF and let the target pass whatever argument it chooses.

How to use Realm's in method with Kotlin

I'm trying to do something like:
val barcodes = arrayOf("123", "456", "789")
realm.where(Product::class.java).in("barcode", barcodes).findAll()
However "in" is a Kotlin function and I can't access the in(String filedName, String[] values) method of RealmQuery object.
Currently I have a java class that does the job and returns the result, but I was wondering is there a more graceful workaround for this?
As stated in the Escaping for Java identifiers that are keywords in Kotlin:
Some of the Kotlin keywords are valid identifiers in Java: in, object,
is, etc. If a Java library uses a Kotlin keyword for a method, you can
still call the method escaping it with the backtick (`) character
For example:
realm.where(Product::class.java).`in`("barcode", barcodes).findAll()

inout String acceptable in AIDL

The documentation states that
all non-primitive parameters require a directional tag indicating which way the data goes; and
primitives are in by default, and cannot be otherwise.
Then they proceed with giving an example where a String is missing the directional tag. Can a String be out or inout in Android AIDL?
Since strings are immutable I'd have to do an assignment on the method handling the call in order to change the string, something like myString = "hello to you too";. I know that in a regular method this argument myString would remain unchanged at the caller side. Is that behavior applied here?

Categories

Resources