Init Blocks will never haunt you again 👻!
Never again be confuse 🤷 by init block in Kotlin, lets resolve which comes first egg(init) or chicken(constructor).
Featured In :
|
---|

Disclaimer : All the assets used as background belongs to respective companies I don't promote them as my own, they are just used to make code relatable and attractive.
Let's understand how it is performed In Java,
Guess the output #1 🕵🏻♂️ Java
☕️
class Guess{
//can you guess the output??
static{ System.out.print("1"); } // static block
{ System.out.print("2"); } // instance initialization block
Guess(){ System.out.print("3");} // constructor
{ System.out.print("4"); }
static{ System.out.print("5"); }
}
//options : a) 15243 b) 23415 c) 31524 d) 24153
Correct Answer ✅
The right output is 15243
.
To arrive to same the conclusion, you need to know some concepts of Java which are :
Static block
is executed when class is fully loaded by JVM. static members areowned by class
not by instance. A class can have multiple static blocks, which will execute in the same sequence in which they have been written in the program.- In Java,
constructors
always callssuper()
at the first line of execution andinitializer blocks
are moved just aftersuper()
call. A class can have multiple initializer blocks, which will execute in the same sequence in which they have been written in the program. Constructors
are called withnew
operator .i.e one of its implementation is invoked when instance of the class is created.
Static Blocks 🧱
Static blocks are used to perform logic on the static fields of the class, most of the time it’s related to complex initialising of static fields before they are ready to be accessed into the main program, for instance :
public static final Map<String, String> spiderman2021;
static {
Map<String, String> cast = new HashMap<String, String>();
cast.put("spiderman", "Tom Holland");
cast.put("mayParker", "Marisa Tomei");
cast.put("flashThompson", "Tony Revolor");
// etc.
spiderman2021 = Collections.unmodifiableMap(map);
}
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
When to use Static block ❓
- For classes whose constructor are not meant to be called but some computation is required in them i.e we need to do some action even if there is no instances.
class SpiderBeltUtil {
private SpiderBeltUtil(){}
final static int webShotsLimit ;
static {
int webShotBattery = // compute webshot battery
int webCartrages = // compute web fluid remaining
int webConsumptionRate = // compute webConsumption per shot
webShotsLimit = cartageCapacity + lastRemaingCartage + webShotBattery;
}
}
- You may wish to do something which should be shared by all objects of that class.
class Multiverse{
private static isMultiverseSpiderManAlive = true;
Multiverse getSpiderVerse(){}
}
Multiverse spiderVerse = new Multiverse();
System.out.println(spiderVerse.isMultiverseSpiderManAlive);
//output: true
Multiverse spiderVerseUltimate = new Multiverse();
System.out.println(spiderVerseUltimate.isMultiverseSpiderManAlive);
//output: true
------------------------------------------------------
class Multiverse{
private static isMultiverseSpiderManAlive = true;
static {
spiderVerse.isMultiverseSpiderManAlive = vemonKillSpiderMan(/*isSuccess*/true);
}
Multiverse getSpiderVerse(){}
}
// In spiderVerse instance
System.out.println(spiderVerse.isMultiverseSpiderManAlive);
//output: false
// In spiderVerseUltimate instance
System.out.println(spiderVerseUltimate.isMultiverseSpiderManAlive);
//output: false
- For a Task which meant to be done only once per class, not be called every time an object is instantiated.
class IronSpiderSuitAnalytics {
static boolean isAllowedToCollectData = false;
static {
isAllowedToCollectData = new remote().getIsSuitAnalyticsEnabled();
}
public void syncData(){
if(isAllowedToCollectData){
//...send data to Avenger Servers
}
}
}
Instance Initialization blocks (IIB) 🆕
Initialization blocks are used to perform logic on the data members of the class. You can initialize member variables or perform some extra operations.
private List<String> villans;
// Intializing blocks
{
villans = new ArrayList<>();
villans.add("Venom");
villans.add("Vulture");
// etc.
}
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
When to use IIB❓
- init blocks are useful to initialize final member variables
class IronSpiderSuit {
final boolean spaceModeEnabled ;
{
spaceModeEnabled = sensorHeight > atmosphereHeight;
}
IronSpiderSuit(){
System.out.println(spaceModeEnabled); // true|false but no error
}
}
- if you implement multiple constructors, then you need to repeat logic into same constructor. Using
{}
you can reduce repetition in all the constructors.
class SpiderMan {
SpiderMan(String suit){
getSpiderBelt();
System.out.println(suit);
}
SpiderMan(){
getSpiderBelt();
System.out.println("Red blue suit...");
}
}
//vs
class SpiderMan {
{getSpiderBelt();}
SpiderMan(String suit){
System.out.println(suit);
}
SpiderMan(){
System.out.println("Red blue suit...");
}
}
- keeping constructor lean by removing DI (dependency injection) independent code outside of it.
class SpiderMan {
SpiderBot spiderBot;
SpiderTracker spiderTracker;
EdihGlass edih;
SpiderMan( EdihGlass edih ){
this.edih = edih;
SpiderBelt belt = new SpiderBelt();
spiderBot = belt.getSpiderBot();
spiderTracker = belt.getSpiderTracker();
}
}
//vs
class SpiderMan {
SpiderBot spiderBot;
SpiderTracker spiderTracker;
EdihGlass edih;
{
//independent from DI (dependency injection)
SpiderBelt belt = new SpiderBelt();
spiderBot = belt.getSpiderBot();
spiderTracker = belt.getSpiderTracker();
}
SpiderMan(EdihGlass edih ){
this.edih = edih; // DI (dependency injection)
}
}
TLDR 📝
Java | Block invoke |
---|---|
Static block | Runs once(when the class is initialized) |
Instance Initialization block | Runs each time you instantiate an object | DI independent code |
constructor | Runs each time you instantiate an object | DI dependent code |
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
Guess the output #2 🕵🏻♂️ Kotlin
💻
Now lets explore a similarly example in the Kotlin,
class Guess{
//can you guess the output??
val value1 = "1".also{print(it)} // data member
init{ print("2") } // init block
val value2 = "3".also{print(it)} // data member
init{ print("4") }
constructor(){ print("5")} // constructor
companion object {
// companion object
init{ print("6") }
val value3 = "7".also{print(it)}
init{ print("8") }
val value4 = "9".also{print(it)}
}
}
//options : a) 678912345 b) 687924135 c) 796813245 d)1234567
Correct Answer ✅
The right output is 678912345
`.
In Kotlin, Constructor
are of two types primary
and secondary
.
- The
primary constructor
is part of theclass header
, mainlimitation
with primary constructor is that itdoesn't have a body
i.e cannot contain code andconstructor
keyword is optional for it unless we explicitly specify visibility modifier.Secondary constructor
always starts withconstructor
keyword, secondary constructor needs to delegate to the primary constructor, either directly or indirectly. Init block
can be used to write initialization code for primary constructor , all initializer blocks and property initializers are executed before the secondary constructor's body. A class can havemultiple init blocks
, which will execute in the same sequence in which they have been written in the program. From this you can make outinit block and IIBs
in java aresame in behaviour
.Companion Object
are used to create property which will be tied to a class rather than to instances .i.e Static members. A companion object is initialized when the class is loaded.Init block inside of companion object
is similar to static block. A companion object can have multiple init block , which will execute in the same sequence in which they have been written in the program.
TLDR 📝
Java | Kotlin |
---|---|
Static block | Companion init block |
Instance Initialization block | init block |
constructor | Primary or Secondary constructor |
With this you understand the basic mapping of Kotlin with Java , now you can scroll back up and read through again what all places you can use init blocks, companions init block and constructors.
Extra : Companion Objects 👩💻
As told above companion objects are used to create properties tied to class rather than instance, a companion object is an object itself, which is Kotlin's singleton pattern implementation, companion object can have their supertypes
and there could be only one companion object in a class.
class SpiderMan : Venom() {
// companion can be extended
init { println("iSpidy")}
companion object : Factory<Venom> {
init { println("OSpidy")}
override fun getInstance(): Venom {
return SpiderMan()
}
}
}
interface Factory<T> {
fun getInstance(): T
}
// does this affect init block call? NO
// can we have init block in interface ? NO , because interface don't
// have constructors
// what about abstract class? YES, example
abstract class Venom {
init { println("iVenom")}
companion object {
init { println("OVenom")}
}
}
// Output
// OVenom // base static
// OSpidy // child static
// iVenom // base init
// iSpidy // child init
Conclusion 💆🏻♀️
With this you would be clear how init block and constructor are invoked, plus some places you would like to consider them.
That's all for today 💻 ! see ya again in next article. Peace!✌
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰