I've been following this article and I'm unsure what the #Stable annotation does. I have seen this documentation but I need an example to better understand.
#Stable is an Annotation that will tell the compiler that it's value will not change and return exactly the same value. This should only be applied to functions or values that are static the whole time.
The main reason why this is used is simple:
Increased performance -> compiler will be faster because you tell him how to handle it.
You can return always the same value, that can't be changed.
Related
I read document, but I don't still get it.
The differences between this
private val myClass: MyClass = mockk(relaxed = true)
and this.
private val myClass: MyClass = mockk()
What I understood is if relaxed is true. Then, all the member fields or methods will return default values. Otherwise, not. is that correct understanding?
If so, setting always relaxed = true is better. But In this video, Ryan uses both. why?
https://youtu.be/60KFJTb_HwU?t=1015
If you're trying to call a mock method that doesn't know what to return and relaxed is not set to true you'll get an exception thrown. This is made, so tests are less likely to introduce unpredictable behavior, due to the default values returned by methods that the developer does not purposely mock.
In the linked video the view methods are probably never called, therefore no "relaxed" is necessary. You can also use "relaxedUnitFun", which works only for methods returning Unit, handy for example for classes responsible for events logging.
This is a double-edged weapon though, as "relaxing" everything deprives you of the security mechanism mentioned above. If this is what you want, you can also configure this globally, check https://mockk.io/#settings-file
To quote their documentation:
A relaxed mock is the mock that returns some simple value for all functions. This allows you to skip specifying behavior for each case, while still stubbing things you need. For reference types, chained mocks are returned.
source
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.
Recently I migrated my project to ViewBinding and as a way to make it less verbose, I decided to expose it through get() property and it seems to be working fine, but some other developers are saying that it may cause memory issues because it's assigning a value to a variable, which I think it's not doing this, since it's exposing through the get() property. Example:
class MyActivity : AppCompatActivity() {
private val textView: TextView get() = binding.textViewID
private val binding by lazy { MyActivityBinding.inflate(layoutInflater) }
}
can someone confirm this?
When you define a property with a getter and no initial assignment, there is no backing field generated. So no, this is not wasting memory.
The way you wrote it on one line looks very similar to code where there is no getter defined and you are assigning an initial value to a backing field. Maybe your colleagues misread your code. I usually define getters on the next line so it looks distinct. Otherwise, it is easy to accidentally omit get() when you intended to include it.
Even if it were creating a backing property, surely you don't have enough views referenced that it would even approach an amount of memory use that you should waste your time worrying about it.
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.
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.