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.
Related
We are a company with 10+ apps all using 10+ internal SDKs, all coded back at the glorious time of the kotlin-android-extensions gradle plugin. We heavily rely on both #Parcelize and synthetic binding (all our views are coded with it). With the newer versions of Kotlin, this plugin is now deprecated in favor of kotlin-parcelize for #Parcelize and View Binding as a replacement for synthetic binding.
We tried to upgrade our Kotlin version from 1.4.10 to 1.6.0 while still using the kotlin-android-extensions plugin. We suddenly had a #Parcelize error reported here, fixed in Kotlin 1.5.0. Except that the fix is not in Kotlin itself, it is in the kotlin-parcelize plugin. And of course as they deprecated kotlin-android-extensions, the later doesn't contain the fix. So in short, in order to fix the issue we have to use kotlin-parcelize.
Knowing that kotlin-parcelize can't be used along kotlin-android-extensions (build error), and that switching all our views from synthetic to view binding will be a hell of a work that will take a tremendous amount of time, what can be done here ? We really want to keep using synthetic binding while being able to upgrade Kotlin to its latest versions.
What looks like the obvious choice is that you need to move from synthetic views as soon as possible although it might not be possible due to lack of resources.
Old-school approach
A solution to get around the Parcelable problem is to figure out the classes that are not properly parcelized and serialize them in an old-school fashion.
Serializing to JSON
I suggest you take a look at the kotlinx-serialization package it's quite handy to read from and write to JSON.
For those that don't work you can provide the following parcelable implementation which would be generic and work all around the codebase:
Ensure that your classes are annotated with #Serializable important that such annotation comes from kotlinx.serialization package and not the java one.
With this generic function you can write any #Serializable object into a parcel.
inline fun <reified T> writeToParcel(out: Parcel, data: T) {
val jsonString = Json.encodeToString(data)
out.writeInt(jsonString.length)
out.writeByteArray(jsonString.toByteArray())
}
And with this other one you should be able to deserialize such object
inline fun <reified T> readFromParcel(input: Parcel): T {
val size = input.readInt()
val bytes = ByteArray(size) { input.readByte() }
val jsonString = bytes.toString()
return Json.decodeFromString<T>(jsonString)
}
You can make them extension function from Parcel to write even less code.
This should get you around the classes that are problematic for the Parcelize extension; it's not as fast as a proper Parcelable implementation but hey, it works.
Side notes
Note that the code has written directly as an answer of this post and hence untested and some parts might need adaptation. And of course, check out the kotlinx.serialization documentation to see how to create the Json encoder and decoder (it's fairly simple)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Considering that starting from version 8 Java is much more clear and readable than Kotlin.
At the and Kotlin code get translated into Java anyway and it is very hard to understand what the code is really doing without plenty of comments that explains it, or autocompletition.
For example:
override fun onClick(v: View) {
val amountTv: EditText = view!!.findViewById(R.id.editTextAmount)
val amount = amountTv.text.toString().toInt()
val action = SpecifyAmountFragmentDirections.confirmationAction(amount)
v.findNavController().navigate(action)
}
How do I know what kind of object is the val "action"?
Considering that starting from version 8 Java is much more clear and readable than Kotlin
Its just matter of taste, everybody has his own opinion, similar to your consideration Google team may found Kotlin good option to be more clear and concise.
Why pushing new dev so much on kotlin if it has nothig more than java?
Kotlin is alot different than just plain Java, the docs itself say much about it, here's brief differences:
Null-safety - Kotlin's type system is aimed at eliminating the danger of null references from code, also known as the The Billion Dollar Mistake.
Your app won't even compile until you remove all possibilities of NPE, otherwise you decide to axing your own feet by null-assertion operator (!!)
Coroutines - Light weight implementation of concurrency model, not only limited to multi-threading but also to the extent of doing deep-recursion, shared mutable-state and structured-concurrency, and also provides a lot of standard utilities for faster development like Flows. Being a lightweight implementation it is slightly faster in many situations than its competitors like RxJava.
Immutability - Proper handling of Collections (difference in read-only and mutable).
Similar goes to variables, Kotlin by default instructs you to use val until you required to change it later in order to provide a thread-safety.
Declaration-site Variance - Kotlin allows you to specify generic variances at declaration-site that will save you a lot of time, and hence less bugs.
Proper function types (i.e. lambda) and higher order functions - There's native support for the lambda expressions, and the support for the inline function makes it possible to counter the performance overhead of memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead.
Smart-casts - no need to cast an object when checks have been made.
if (variable is String) {
println(variable.length) // no need to cast to String :P
}
Functional extensions - let, run, also, apply, with, use. These are very useful in concise code and hence boosts productivity.
// Java version
var a = Api.result();
Log.i(Tag, a.toString());
return a;
// Kotlin version
return Api.result().also { Log.i(Tag, it.toString()) }
Default parameters - You can mark a field as optional and just use 1 single function which is easier to manage later on rather than overloading function like 5 times and manage them all when updating a piece of code.
Native support for delegation - Defining getters and setters once and use them for as many field/properties as you want. There are delegates provided by std-lib like lazy (do-not allocate memory in RAM till property is accessed for the first time), observable (observe the changes in variable with both old and new value), etc.
Delegation of classes - You can implement a class using another object, useful when you want to extend some functionality of class but want to let other untouched. For examples see: Delegation of Classes
Inline functions and reified generics - In java it is impossible to use generics inside of a function because of JVM type-erasure. But this is not the case in Kotlin, you can embed the function into the callsite (at the compile time) using inline modifier and access generics via making it reified.
Destructing Declarations - Create multiple variable in same line using a destructing object, see Kotlin: Destructuring Declarations for examples.
Edit:
Forgot to put the answer to the code block, the amount has the same type returned by toInt(), and action has the same type as returned by confirmationAction(amount). Using an IDE will show that to you the inferred types in front of the variable names, you can also jump at the sources through some Ctrl+MouseClick at the call-site.
type of val action is same as the return type of confirmationAction method in SpecifyAmountFragmentDirections class
It's just that you have been using Java for long time and new to kotlin so you finding kotlin hard to understand.It's just matter of time and once you start using it regularly you will find it easier to understand and read.Moreover lines of code usually becomes less in kotlin.
UPDATE based on comments-
Kotlin has some advantages in comparison to java like it is more safe against NullPointerException which all android developers face many times in java and it is less verbose and less code can mean chances of fewer bugs.So new developers are recommended to learn kotlin for 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}")
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.
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.