I created my class (exending Activity) with an attribute int a.
The attribute is automatically initialized to 0 in the method onCreate().
Is it normal?
This is normal. You see, "int" is a primitive type. It is not an object, and so, it cannot hold a "null" value. If you want your variable to be null at onCreate(), you must change its type to the Object representation of it. The "Integer" class represents the primitive type "int".
From Official Java Tutorial:
Fields that are declared but not initialized will be set to a
reasonable default by the compiler.
Check default values for each data type: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
in the method onCreate().
No, it's not initialized in onCreate(). It's initialized when object of your class is instantiated.
0
Yes it is. Variable of int is primitive type can only hold numeric values and unless you initialize it other way it will be assigned 0 (contrary to i.e. Integer which can also be null).
See docs:
https://docs.oracle.com/javase/tutorial/java/javaOO/index.html
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Related
This question already has answers here:
Smart cast to 'Type' is impossible, because 'variable' is a mutable property that could have been changed by this time
(12 answers)
Closed 1 year ago.
I am studying Android and I am also studying Kotlin.
While writing Android code, I was curious about using it in a let function.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var curFrag: Fragment? = null
curFrag = fm.primaryNavigationFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// curFrag?.let { transaction.hide(curFrag) } // error.
curFrag?.let { transaction.hide(it) }
}
}
ERROR
Smart cast to 'Fragment' is impossible, because 'curFrag' is a mutable property that could have been changed by this time
In the lambda expression of let(), T is curFrag and the type is Fragment? is.
And T(curFrag) can be replaced by it.
But the moment I used curFrag instead of it, the IDE displayed an error message.
Later, when I checked the type of it, it was Fragment? It was not a Fragment type.
Honestly, I don't understand well.
I don't know why it is automatically smart cast and should only be used for immutable variables.
Kotlin is a null safe language, it tries to eliminate every possible null references from the code. You can perform a nullability check on the variable and then can use it like this
if(curfrag != null) { transaction.hide(curFrag)
This too will only work if variable curfrag is immutable (that means a local variable which is not modified between the check and the usage or a member val which has a backing field and is not overridable), because otherwise it might happen that curfrag changes to null after the check from some other thread.
But Safe calls ?. with let always gives us non nullable result, what Safe calls operator ?. does is, it only performs any operation following it, only if the variable is not-null otherwise it returns null.
It works with all mutable types or member var, It check for the null once and then provides the result. If value is non null it performs the defined operation otherwise skips it. it refers to the copy of that non-null value.
So when you do this
curFrag?.let { transaction.hide(curFrag) }
curFrag can be null as you are directly passing a nullable value.
But in this case
curFrag?.let { transaction.hide(it) }
it only passes value if it's a non-null value.
The let function basically creates a new variable with the same value as whatever you called it on, so it is not really smart-casting the original property.
If you use ?.let, let isn't even called if the value was null. The safe call means the receiver let is being called on is not a nullable value to begin with because otherwise let isn't called at all. The it inside let is just a reference to what it was called on.
Effectively, though it is conceptually similar to smart-casting. There is not really a way to write equivalent Kotlin code that does what ?.let is doing because the ?. safe call is a special operator that has no expanded form.
What is the purpose of defining 2 variable in this tutorial? Why don't we use 1 variable instead and accessing view with it?
https://developer.android.com/topic/libraries/view-binding#usage
The getter on the second variable (binding) uses the !! operator to assert that the variable is non-null when accessed.
Essentially the backing field (_binding) is nullable in order to represent the state before onCreateView and after onDestroyView whereas the getter provides an easy way to access the field without scattering null checks or assertions elsewhere in your code.
I am shifted from c# to kotlin. Not sure how kotlin handles reference type and value type data types, also not sure how kotlin handles the reference when we assign one variable to another like following
var x = 14
var y = x
y = 5
println(x)
I am not sure it will print 14 or 5
Thanks
In your example, it is irrelevant how Kotlin would treat values vs. references because you are reassigning the variable, not modifying it through a member function or property.
If we modify the example so your number is wrapped in a mutable object like this:
class WrappedInteger(var value: Int)
var x = WrappedInteger(14)
var y = x
y.value = 5
println(x.value) // prints "5"
The value of x is modified to 5 when you call the setter for y.value because y is pointing to the same object as x.
I think C# is the same way, but you can sum up the behavior like this: Kotlin always passes by value, and references are immutable pointers that are implicitly dereferenced when you access their members. So references are also passed by value...you just can't see or modify the value (the address of what it's pointing to).
Kotlin does not have structs like C#, so you can't pass a group of data by value (copying it). It does have data classes, which come with a pre-generated copy() function that you can call manually. You can also define all the properties of your data class as read-only val, so you don't have to worry about the passed object being modified by some function.
I was glancing through this function getLocationOnScreen()
void getLocationOnScreen (int[] outLocation)
Computes the coordinates of this view on the screen. The argument must be an array of two integers. After the method returns, the array contains the x and y location in that order.
What I don't understand here is that if I am passing an array something like this,
int position[] = new int[2];
view.getLocationOnScreen(position);
The function being return type being void how does my array contains those values without the function returning it ?
Note: This question is not a duplicate of the below as it explains the working of the 2 methods.
getLocationOnScreen() vs getLocationInWindow()
The primitive type will pass variable by copy it value ,so the value will not change after the method finished.But as you see ,you created an array type using keyword new ( new int[2]),so the this variable is an object type, when you passed param to the method it would be reference of the array.
In Java the primitive type pass by value while object type by reference and you can not chose to pass address like C using operation &
It's about the reference an object from memory. You are sending your object adress which means the adress referencing your object. And the function using this adress of your object. With that way the function can change your object's value but can not change the adress.
Here, this idea coming from C language
And usage in java:
Java works exactly like C. You can assign a pointer, pass the pointer to a method, follow the pointer in the method and change the data that was pointed to. However, you cannot change where that pointer points
Which parameter passing method is used in Android? Pass by reference or Pass by Value? Please provide an Android Specific example for the same.
All parameter passing in Java is by value.
Here is a nice article with all the details.
just like a normal Java Application:
Objects are passed by reference,
primitives are passed by value