C# nameof(Class) equivalent in Kotlin - android

In C# we have nameof() operator which return name of the class in string, what is the equivalent in Kotlin?
My use case would be something like this for
internal val TAG = nameof(MyCustomActivity)

MyCustomActivity::class.simpleName
Will output MyCustomActivity
MyCustomActivity::class.qualifiedName
Will output <your_package>.MyCustomActivity

As mentioned in the accepted answer, the <class>::class.simpleName property will provide a result similar to that of the C# nameof operator. However, unlike nameof, ::class.* cannot be evaluated at compile-time.
This is relevant, as cases where you may use the nameof operator in C#, you cannot equivalently do with ::class
For example, AspectJ's #Around annotation.
The following will fail, as you cannot interpolate non-compile-time† expressions:
#Around("#annotation(${MyAnnotation::class.simpleName})")
If Kotlin supported nameof in the same fashion as C# (where it can be used in that context) one could do this:
#Around("#annotation(${nameof(MyAnnotation)})")
So, while the accepted answer provides a functionally similar manner of resolving symbol names in Kotlin, it cannot be used with the same flexibility as nameof in C#.
† Interestingly, until writing this answer I didn't realize you can interpolate constant value (and other compile-time evaluable) expressions into annotation parameters; the following will compile:
const val FOO = "foo"
#MyAnnotation("${FOO} ${1 + 1}")

Related

How to tell the difference between Java and Kotlin code?

As a beginner to Android app development, I am finding code examples that do not identify whether they are written in Java or Kotlin. Even StackOverflow questions frequently omit the language tag.
Is there an easy "tell" in the code where you can immediately see which language is used? For example, I can distinguish C and C++ very quickly from certain elements of the syntax, header use, and library functions.
Are there any quick and "obvious" ways to distinguish Java from Kotlin? I want to be exploring Kotlin and not adding to my (immense) confusion by studying irrelevant code.
some obvious traits for kotlin:
as already mentioned the most obvious is semicolons, although you can
add them and they will just be ignored
variables marked with question marks (nullability) val foo:String? and the usage of val/var/lateinit
class Foo : Something() <-- this is inheritance, there's no extends
or implements
if files are involved, kotlin files end with .kt
any reference to companion object
personally for me the biggest indicator:
fun :) function declaration :
fun foo(): String
If the code has used "val", "var" keywords then 99% it is Kotlin.
Kotlin Keywords and operators. https://kotlinlang.org/docs/keyword-reference.html
Java Language Keywords. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
Most likely kotlin:
val
var
fun
nameX: TypeX
nameX : TypeX?
object:
open class
when
#
:
sealed
!!
->
"$name or ${name}"
etc
Most likely java:
; semicolon
TypeX nameX
void
extends
implements
public class
instanceof
etc
Java has mandatory semicolons ';' while Kotlin doesn't. The types in Java are int, string, char, etc while in Kotlin they are capitalized(String, Int, Long, Char), also Kotlin can infer the type of a variable most of the time ;)
i found this article helpful
as guys told kotlin is a language Is introduced by null safety and without any smicolons force
and you can find some key in syntax like
**[fun,as,let,also,apply,val,var,lateinit,...]**
So, which one is better and should you use it? The answer to that question depends on your needs. If you’re looking for a language with solid support from Google, then Kotlin may be the best choice, as Android Studio 3 now supports Kotlin development. However, if you need speed or want an open-source project with more flexibility (especially in terms of third-party libraries), Java might be the right option for you.
refer to this article
If the file end with .kt, it is Kotlin.

What is the meaning of "ClassInstance.[Someclass::class.java]" in Kotlin?

I've seen people using ViewModelProvider[Someclass::class.java] instead of ViewModelProvider.get(Someclass::class.java), and it compiles in Android Studio. The problem is that I couldn't find any documentation of such usage online.
With kotlin you can add operator modifiers to your function. So if you have some class with a get function and you might want to access it with [], like an array or map, you could add operator modifier.
Square brackets are translated to calls to get and set with appropriate numbers of arguments.
So this only works for functions with name get or set!
class Provider {
operator fun get(key: String)
operator fun set(key: String, value: String) { ... }
}
Then you can call the function like:
Provider().get("key") // IDE hint: should be replaced with indexing operator
Provider()["key"] // calls get()
Provider().set("key", "value") // IDE hint: should be replaced with indexing operator
Provider()["key"] = "value" // calls set()
Reference
See Kotlin Operator overloading
Kotlin allows operator overloading by marking a function as an operator function. The square brackets notation is one of these operators (indexed access operator).
Kotlin automatically interprets Java functions as operator functions if their name and signature match the requirements of a Kotlin operator function. In this case, it interprets functions named get as an "indexed access operator" if they return something, which allows you to use square bracket notation.
ViewModelProvider[Someclass::class.java] is a shorter version of ViewModelProvider.get(Someclass::class.java) there is no differences.

Is this usecase of kotlin reified type useful

The Reified Type parameters support run-time access to types passed to functions. I understand that this can be useful in certain scenarios to avoid reflection.
But there are examples of creating extension functions with reified type parameters which simply wrap T::class.java syntax in a method like below.
inline fun <reified T > Context.systemService() =
ContextCompat.getSystemService(this,T::class.java)
The kotlin reference mentions for the below usage the call-site is not pretty. Why is the following usage discouraged?
ContextCompat.getSystemService(this, NotificationManager::class.java)
Instead we can now write it like this :
systemService<NotificationManager>()
Are there any other benefits in such a scenario except that the code looks cleaner?
Note: the example is from I/O' 18
This is entirely up to personal opinion, as both functions will do the same thing.
People will tend to consider the reified Kotlin extension method more idiomatic because it makes use of advanced language feature to provide simpler syntax than what you'd otherwise have to use. Doesn't mean you absolutely have to use it - decide if you like it for yourself.

Why use inline without lambdas

I'm trying to understand how to use inline modifier correctly. I understand general case, when we inlining lambda to prevent excess allocation, as described in docs.
I was inspecting kotlin stdlib and found in _Strings.kt the following piece of code:
#kotlin.internal.InlineOnly
public inline fun CharSequence.elementAtOrNull(index: Int): Char? {
return this.getOrNull(index)
}
What's the reasoning behind using inline here?
This particular function and a few others in kotlin-stdlib are marked as #InlineOnly so that they are not present in the actual stdlib class files and are only available for the Kotlin compiler to inline them. The goal that is achieved in this way is reducing the methods count in the artifacts, which matters for Android.
Apart from that, using inline functions without lambdas is useful for reifying type parameters.
There is still overhead, no matter how minor, that can be avoided.
A similar discussion on Inline Extension Properties.
A post on Kotlin Extensions which gets down into the bytecode effects
I would say that is related to efficiency. Instead of calling functions elementAtOrNull and thus, getOrNull this one is directly called.

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()

Categories

Resources