Topic: 5 Understanding Variables in Android
This is our fifth topic from learn android from basic to advance series
Hello Devs, Today we will discuss Variables in our series and I know I know devs that I want to cover this topic first but I am also a human, and as you all know mistakes only happen by humans. OK moving on to the topic. So in this topic, we talk about why it is important and how we use this in development.
Variables
Variables are like containers they store different kinds of data. This is a fundamental component of every programming language. There are different types of variables available in programming.
Types of Variables
Primitive Variables:
These are the basic building blocks for storing simple data types like integers, floating-point numbers, characters, and boolean values. In Android, you'll often use these primitives to store simple data such as user input, numeric values, or flags.
int age = 25; float weight = 65.5f; char grade = 'A'; boolean isActive = true;
Reference Variables:
In Android, you'll frequently work with objects and collections. Reference variables store memory addresses that point to objects or collections rather than the actual data. For instance, when dealing with UI elements like TextViews or Buttons, you'll often use reference variables to interact with them programmatically.
TextView textView = findViewById(R.id.textView); Button button = new Button(context); ArrayList<String> stringList = new ArrayList<>();
Instance Variables:
These are variables declared within a class but outside of any methods. In Android development, instance variables are commonly used to represent the state of an object or to store data that needs to persist throughout the object's lifecycle. For example, in an Activity or Fragment class, you might use instance variables to store UI components or data fetched from a database.
public class MyActivity extends AppCompatActivity { private String username; private int score; // Constructor, methods, and lifecycle callbacks... }
Static Variables (Class Variables):
Static variables are associated with the class rather than with any particular instance of the class. In Android, static variables are less common but can be useful for storing global configuration values or constants that are shared across multiple instances of an Activity or Application.
public class Constants { public static final String API_KEY = "your_api_key"; public static final int DEFAULT_TIMEOUT = 5000; // More constants... }
Local Variables:
Local variables are declared within a method or block of code and are accessible only within that method or block. In Android, you'll use local variables to perform temporary calculations, store intermediate results, or pass values between different parts of your code.
public void calculateTotal(int a, int b) { int total = a + b; System.out.println("Total: " + total); }
Final or Constant Variables:
These variables hold values that cannot be changed once they are assigned. In Android development, constants are often used for things like defining key names for Intent extras, specifying request codes for permissions, or setting default values for configuration parameters.
public class Constants { public static final String INTENT_KEY_USER_ID = "user_id"; public static final int REQUEST_CODE_PERMISSION = 1001; // More constants... }
Parameter Variables:
Parameter variables are used to pass data into methods or functions. In Android, you'll frequently use parameter variables to pass information between different components of your app, such as passing data from one Activity to another via Intent extras or passing callback listeners to asynchronous tasks.
public void sendMessage(String message) { // Logic to send message... } // Example of passing data between activities using Intent extras Intent intent = new Intent(this, NextActivity.class); intent.putExtra(Constants.INTENT_KEY_USER_ID, userId); startActivity(intent);
As you see in the example I wrote something like Int, float, etc. So what is this? it's a Data type. Basically, Data types are used to check what kind of data is stored in variables. Let's explore the Data Types.
Types of Data Type
As we all know that we use two kinds of languages for developing applications in Android. Java and Kotlin so first we discuss about Java data type after that Kotlin data type.
Java:
Primitive Data Types: In Java, primitive data types are predefined by the language and represent basic types of data. These include:
int: Used to store integers (whole numbers) such as 1, 2, -5, etc. This data type uses 4 bytes(32 bits) of memory storage.
int number = 10;
float: Used to store floating-point numbers (numbers with decimal points) such as 3.14, 2.5, etc. This data type uses 4 bytes(32 bits) of memory storage.
float floatValue = 3.14f;
double: Similar to float but with higher precision. This data type uses 8 bytes(64 bits) of memory storage.
double doubleValue = 3.14;
boolean: Used to store true or false values. This data type uses 1 byte (8 bits) of memory storage.
boolean isTrue = true;
char: Used to store single characters like 'a', 'b', 'c', etc. This data type uses 2 bytes(16 bits) of memory storage.
char letter = 'A';
byte, short, long: Additional integer types with different ranges. byte uses 1 byte, short uses 2 bytes, and long uses 8 bytes of storage.
//Byte byte byteValue = 100; //Short short shortValue = 1000; //Long long longValue = 1000000L;
Reference Data Types: These are non-primitive data types that are created using classes, arrays, interfaces, etc. This includes:
String: Represents a sequence of characters, such as "Hello, World!".
String message = "Hello, World!";
Object: The root class for all other classes in Java.
Object obj = new Object();
Arrays: Used to store multiple values of the same type in a single variable.
int[] numbers = new int[10];
Reference data types (objects) consume memory dynamically based on their size and structure.
Kotlin:
Primitive Data Types: Kotlin has similar primitive data types to Java, but it provides some additional features and improvements:
Int, Float, Double, Boolean, Char: Similar to their counterparts in Java.
// Int val number: Int = 10 // Float val floatValue: Float = 3.14f // Double val doubleValue: Double = 3.14 // Boolean val isTrue: Boolean = true // Char val letter: Char = 'A'
Byte, Short, Long: Also available in Kotlin.
// Byte val byteValue: Byte = 100 // Short val byteValue: Byte = 100 // Long val longValue: Long = 1000000L
Reference Data Types: Kotlin treats classes as reference types, and it provides several built-in classes for common data types, such as:
String: Represents a sequence of characters. Memory usage depends on the string's length.
val message: String = "Hello, World!"
Array: Used to store multiple values of the same type. Memory usage depends on the size and type of elements.
val numbers: IntArray = intArrayOf(1, 2, 3, 4, 5)
Collections (List, Set, Map): Kotlin provides a rich set of collection classes for storing and manipulating data. Memory usage varies based on the size and contents of the collection.
// List val list: List<String> = listOf("apple", "banana", "orange") // Set val immutableSet: Set<String> = setOf("apple", "banana", "orange") // Map val immutableMap: Map<String, Int> = mapOf("apple" to 1, "banana" to 2, "orange" to 3)
As you see in the Kotlin example I used the keyword val
. Let's talk about Val and other keywords.
Val
val
is a keyword in Kotlin used to declare read-only variables, also known as immutable variables. Once assigned, the value of aval
cannot be changed.It is similar to declaring variables with the
final
keyword in Java.val
properties can be initialized at runtime.val
is typically used when the value of a variable should remain constant throughout its lifetime.val PI = 3.14 val name = "John"
Var
var
is another keyword in Kotlin used to declare mutable variables. Unlikeval
, the value of avar
variable can be changed after it's initialized.var
is used when the value of a variable is expected to change during the program execution.var count = 10 var message = "Hello"
Mutable
In Kotlin,
mutable
is a prefix used to indicate that a type is mutable, meaning its contents can be modified after creation.It is commonly used with collection types like
MutableList
,MutableSet
, andMutableMap
, where elements can be added, removed, or modified.val mutableList: MutableList<String> = mutableListOf("Apple", "Banana", "Orange") mutableList.add("Mango")
Static
In Java,
static
is a keyword used to declare class-level variables and methods. It indicates that the variable or method belongs to the class itself, rather than to instances of the class.// Package-level function (placed within a utility class) public class Utils { public static void doSomething() { // Function body } } // Companion object (static inner class) public class MyClass { public static final int CONSTANT_VALUE = 10; public static void staticMethod() { // Method body } }
In Kotlin, there's no direct equivalent of the
static
keyword. Instead, Kotlin uses package-level functions and properties orcompanion object
to achieve similar functionality.// Package-level function fun doSomething() { // Function body } // Companion object class MyClass { companion object { const val CONSTANT_VALUE = 10 fun staticMethod() { // Method body } } }
Constant:
Constants are variables whose values cannot be changed once they are assigned. They are typically declared with the
final
keyword in Java or theconst
keyword in Kotlin.const
properties can be initialized at compile time.Constants are often used for values that remain constant throughout the program's execution, such as configuration parameters or API keys.
const val PI = 3.14 const val API_KEY = "your_api_key"
Final:
In Java,
final
is a keyword used to declare constants, prevent method overriding, and make variables immutable.public final class MyClass { public final double PI = 3.14; public final void someMethod() { // Method body } }
In Kotlin,
final
is not a keyword but is implicitly applied toval
variables, making them read-only.final class MyClass { final val PI = 3.14 final fun someMethod() { // Method body } }
lateinit:
lateinit
is nothing more than a promise. You promise Kotlin that you will initialize it before using it. It's like telling Kotlin, "Hey, I'll give you the value later, I promise!"Late initialization applies only to var fields. This means
lateinit
applies only to reference types.lateinit
is handy when you need to delay initializing a variable until later in your code, but you're sure it'll be initialized before you use it. Just be cautious not to forget to initialize it, or you'll run into runtime errors!
lateinit var name: String
Now, you can use name
without initializing it immediately. But remember, you must initialize it before accessing its value, otherwise, you'll get an exception.
name = "John" // Initialize the variable before using it
println(name) // Now you can use it safely
Lazy
Lazy initialization allows you to defer the initialization of a variable until the moment you first use it.
Imagine you have a task that takes a lot of time or resources to complete, but you don't want to do it until you absolutely have to. That's where lazy initialization comes in handy.
Lazy initialization applies only to val. This means lazy applies only to primitive types.
Lazy initialization is a useful technique when you want to delay the initialization of a variable until it's needed, improving performance and resource usage in your app.
val expensiveData: String by lazy {
// This block of code will be executed only when 'expensiveData' is first accessed
println("Initializing expensiveData...")
"This is the expensive data"
}
// Somewhere else in your code
println("Do some other work first")
println(expensiveData) // This will trigger the lazy initialization
LiveData:
LiveData
is an observable data holder class provided by the Android Architecture Components.It's designed to hold and deliver data to other components, such as UI controllers (like Activities or Fragments), in a lifecycle-aware manner.
LiveData
is typically used to represent data that needs to be observed for changes, such as data fetched from a database or network.It ensures that UI components only update when they are in the active state, preventing issues like memory leaks and inconsistent UI states.
val currentUser: LiveData<User> = userRepository.getCurrentUser() currentUser.observe(this) { user -> // Update UI with the current user data }
Memory Considerations:
Primitive vs. Reference Types: Primitive data types generally consume a fixed amount of memory, whereas reference data types (objects) consume memory dynamically based on their size and structure.
Memory Overhead: In addition to the actual data, objects in Java and Kotlin incur memory overhead for storing metadata, such as class information, synchronization locks, and garbage collection information.
Garbage Collection: Since Java and Kotlin use garbage collection to reclaim memory from unused objects, excessive memory usage can lead to increased garbage collection overhead and potential performance issues.
OK, Devs it's time to wrap up the topic. As you see some words like Memory Leak and garbage collection. So what is this? and how important it is for the application's performance. everything we discuss in our next blog and topic from the Learn Android from basic to advanced series. See you at the next blog devs.
Connect with Me:
Hey there! If you enjoyed reading this blog and found it informative, why not connect with me on LinkedIn? π You can also follow my Instagram page for more mobile development-related content. π²π¨βπ» Letβs stay connected, share knowledge and have some fun in the exciting world of app development! π