class constants name use full upper case with underscores
Compiler knows that if it is static field then static initializer is called only once and constructor is never called. But if it is a non-static field then we can initialize in constructor since it is called only once.
We could say that a variable is effectively final if the compiler wouldn’t complain were we to declare it final
You cannot change the value of variable inside the lambda, because that will conflict with the final philosophy
Why it is imposed?
If we can change the value of the local variable later in the code block, then Visibility issues will happen and all the threads executing the lambda will not see the value
For static and instance fields, we can use volatile synchronization for example to avoid this issue
Interesting points:
For a local variable to change its reference, In java you can only do in the current scope
If you call a method with the variable as argument, primitives values get copied, while reference objects copy reference, so the variable’s reference never changes
Java has neither closure nor pointers (also what will you call as closure??)
Hence it is easy for compiler to check if the local variable is really final effectively or not
Atomic Variables
Since we cannot update the value inside the lambda, we can use holder class such as AtomicInteger to update the integer local variable for example
class MyTask { private String instanceField = "hola"; void exec() { instanceField = "newString"; String localVariable = "lala"; Arrays.asList(1, 2, 3) .forEach(num -> { // instance field, hence fine! System.out.println(instanceField); // this is effectively final, hence fine! System.out.println(localVariable); }); fun(localVariable); } void fun(String localVariable) { localVariable = "I am trying to change"; }}
final vs virtual
Java does not have virtual keyword unlike for example C# or C++
A virtual method is the one which shows runtime polymorphism via overriding it
All methods in Java are virtual by default
Only case when method is not virtual is when it is marked final
Virtual method:
It is declared within the parent class and can be redefined by the child class.
Pure Virtual method:
It is virtual method that is not defined at all in class.
In Java world we call it abstract methods or interface methods (which are abstract by default)
The difference lies in the compile time vs runtime polymorphism through dynamic dispatch
C# example:
virtual and override are being used together
Draw() shows compile time polymorphism
Draw2() show runtime polymorphism via dynamic dispatch
using System;class Shape{ // runtime polymorphism // will show dynamic dispatch public virtual void Draw() { Console.WriteLine ("Drawing a shape..."); } // compile time polymorphism // will not show dynamic dispatch public void Draw2() { Console.WriteLine ("Drawing a shape..."); }}class Circle : Shape{ public override void Draw() { Console.WriteLine ("Drawing a circle..."); } public void Draw2() { Console.WriteLine ("Drawing a circle..."); }}public class Test{ public static void Main(string[] args) { Shape shape = new Circle(); shape.Draw(); // Circle class: Drawing a circle... shape.Draw2(); // Shape class: Drawing a shape... }}