Classes
- A Java class file is a file containing Java bytecode that can be executed on the Java Virtual Machine.
- A class could be public, default, strictftp, final, and abstract modifiers.
Public | Class from all packages access to public class. |
Default | Class should be same package, or else it will not be not visible. |
Strictftp | Any method code in class will confirm to IEEE 754 rules for floating points. |
final | Cannot be modified/ Improved. Limited use in case of Security/ Safety scenarios. |
Abstract | Never be instantiated, Only aim is to extend. |
Interfaces
- Interface is a contract about what a class can do .
- Interfaces can be public/ default, but cannot be final or abstract
- Interface Methods are public, abstract.
- Interface variables are constants -> public static final.
- Default Interfaces
- default can be assigned only to interfaces and should have concrete body
- Can only be public not private/ protected/ static/ final/ abstract.
- When you have 2 default interface methods, the impl class have to override the interface method.
- Default Interface methods can be overridden.
- Static Interfaces
- Can only be public not private/ protected/ default/ final/ abstract.
- When invoking a static interface method. method’s type must be included in the invocation, However instance variables can be invoked without reference, with refernce, or InterfaceName. Invoking static method using instance reference was a mistake that Java designers had made which is corrected in interfaces.
Members
- Public members : No explanation needed as the name suggests.
- Private members : Can’t be accessed by code in any class other than declaring class.
- Protected members : Accessed through inheritance by a subclass
- For a subclass outside the package, the protected member can only be accessed through inheritance i.e childRef.privateMethod
- default members : Accessed only if in same package
- Final Methods : Prevent method being overridden, and enforces API functionality.
- Abstract Methods : A type of method which is declared but not implemented.
- Illegal to not make class abstract if it has any abstract methods
- You can however have abstract class without any abstract methods
- The first concreate class should implement all abstract methods.
- Can’t be static/ final/ private
- Synchronized Methods : Method Accessed by one thread at a time
- Methods with var-args : Java allows you to create method that can take variable number of arguments.
- arguments : Things you specify while invoking method
- parameters : Things in method signature that indicate what the method must receive.
- Constructors : Objects are constructed, every-time a new object is created, a constructor is invoked.
- Constructor cannot be marked final/ abstract
- Constructor has no return type
- Construtor name same as Class Name
Variables
- Primitive variables : Once declared the type cannot change, 8 types
Type | Bits | Bytes | Min Range | Max Range | Notes |
byte | 8 | 1 | -2^7 | 2^7 – 1 | First bit is Sign Bit hence 2^7 Max range in Positive side is one short to accommodate 0 |
short | 16 | 2 | -2^15 | 2^15 – 1 | |
int | 32 | 4 | -2^31 | 2^31 -1 | |
long | 64 | 8 | -2^63 | 2^63 – 1 | |
float | 32 | 4 | Determining the range is complicated https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html | ||
double | 64 | 8 | Determining the range is complicated https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html | ||
boolean | Virtual Machine dependent | ||||
chartype | 16 | 2 | Char is really an integer type, and can be assigned to any type that can hold 2^16 which means anything from int onwards. |
- Reference variables : Used to refer an object
- Instance variables : Initialised when class is initialised, and is declared inside class, but outside method
- local variables : A variable declared within the method.
- final variables : Once the variable is assigned a value, the value can’t be altered.
- There are no final objects, only final references.
- transient variables : JVM skips variable as we attempt to serialize the object containing it.
Enums
- Enums are simply specialised classes similar to Singleton classes with private Constructor, Values, ValueOf method implementations.
- Java lets you restrict a variable to having one of only a few predefined values from an enumerated list and these are achieved by enums.
- Enums can have
- Overriding
- Constructor
- Instance Variable
- methods
OOPS Principles
- Abstraction
- In Java, abstraction means simple things like objects, classes, and variables represent more complex underlying code and data.
- Encapsulation
- The practice of using getters and setters to hide instance variables. This helps to make changes in your code implementation without breaking the code of others.
- Inheritance
- Object-oriented programming allows classes to inherit commonly used state and behavior from other classes.
- Inheritance is there everywhere in Java, every class in Java Inherits Object.
- It heps to promote code reuse, and to use polymorphism.
- IS-A : It is a way of saying – This thing is a type of that thing. Car extends Vehicle means Car is a Vehicle
- HAS-A : A Horse IS-A Animal. A Horse HAS-A Halter. HAS-A relationship allows you to design classes that follow good OO practices by not having monolithic classes that do a gazillion different things.
- Polymorphism
- Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.
- A class cannot extend more than one class : that means one parent per class as otherwise leads to scenario of Deadly Diamond of Death.
- Method invocations allowed by the compiler are based solely on the declared type of the reference, regardless of the object type, hence downcasting is not default permitted. Also please note explicit downcasting will fail at runtime if the object is diff.
- Overriding : Allows a child class to provide a specific implementation of a method that is already provided by parent class.
- Happens at RunTime
- Rules of Overriding:
- Argument List must exactly match.
- Return type must be the same as, or subtype of the return type.
- Access level can be wider but not restrictive.
- Overriding method can throw narrower exception but not broader.
- protected non subtype, static, final, private can’t be overriden.
- OverLoading : Lets you reuse the same method name in a class, but with different argument
- Overloaded methods MUST change the arguments list.
- Happens at Compile time
Constructor
- Every class, including abstract classes, MUST hava a constructor, but abstract class constructor can only be invoked by constructor chaining. The rules for writing constructor are
- Constructor name should match class
- Any access modifier
- No return type
- First statement super/ this
- Only way a constructor can be invoked is from within another constructor.
- Only static variables ans methods ca be invoked as part of call to super/ this.
- Constructors are never inherited.
Java Compiler Fundamentals
JIT Compiler: Java programs are converted to bytecode and to Machine code. JIT helps JVM by compiling some of the byte code into machine code at runtime which increases the performance of JVM.
- Class Loader : When an class is requested by the JVM, the class is loaded by Class Loaders, there are 3 of them
- Bootstrap : Loads Java core lib.
- Extension : loads class at $JAVA_HOME/lib/ext
- System/ Application : Loads application classes.
When a class requested Class loaders follows a delegation model where on request to find a class or resource, a ClassLoader instance will delegate the search of the class or resource to the parent class loader, and it fails then the child loads. Read more at Blog
Volatile, Atomic & Synchronized
Volatile : volatile
is a variable access modifier that forces all threads to get the latest value of the variable from the main memory, which means that modifying its value immediately affects the actual memory storage for the variable. The compiler cannot optimize away any references made to the variable. This guarantees that when one thread modifies the variable, all other threads see the new value immediately. However, This also means that when a thread reads a volatile
variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
When to use: One thread modifies the data and other threads have to read the latest value of data. Other threads will take some action but they won’t update data.
Atomic: AtomicXXX
classes guarantee that operations made on them occur in an atomic fashion, i.e., that all of the substeps of the operation are completed within the thread they are executed and are not interrupted by other threads. For example, an increment-and-test operation requires the variable to be incremented and then compared to another value; an atomic operation guarantees that both of these steps will be completed as if they were a single indivisible/uninterruptible operation. Another way of saying that is that the i++ operation would be executed without any side effects(write before reading), whereas for volatile variables the side effects of this change could be read.
AtomicXXX
classes support lock-free thread-safe programming on single variables. These AtomicXXX
classes (like AtomicInteger
) resolves memory inconsistency errors/side effects of modification of volatile variables, which have been accessed in multiple threads.
When to use: Atomic instance variables can be safely used with multiple threads.
Synchronizing: Non-static Synchronization occurs on the object by acquiring its lock(monitor). This means that one thread calling a synchronized method of an object will lock the synchronized method from being executed by any other thread, also any other synchronized method in that object. Static synchronized methods will lock the object itself, such that no thread is able to acquire a lock on any of the static synchronized methods of that class.
AromicXXX classes can be equated with Volatile + Synchronized, however, the implementation of AtomicXXX focuses on non-blocking algorithms like compare and swap operation.
Design Pattern: As programmers often encounter the same problem repeatedly, rather than everyone coming up with their solutions, we use a “best practice” solution that has been documented and proven to work. Read more at https://www.jonesjalapat.com/2021/10/04/design-patterns/
Assertions and Java Exceptions
Assertions: Assertions let you test your assumptions during development, but the assertion code basically evaporates when the program is deployed. We are never supposed to handle an assertion failure. An example of assertion
assert ( y > x) : “y is ” + y + ” x is ” + x; code after colon must resolve to a value.
java -ea com.anonymous.TestClass, enable assertions at runtime since it is disabled by default
In a real sense use assertions to check for cases that are never supposed to happen. Also, the rule is that an assert expression should leave the program in the same state it was in before the expression.
Exception Handling: We need exception handling in code to better handle the exception, and usually a common pattern called ‘handle and declare’ is used, and handling could just be propagating further and finally doing handle and declare at that commonplace. Note that the parameter e of a multi-catch block cannot be assigned because it is final.
Autocloseable Resources: From Java -7, we are able to automatically close resources using automatic resource management provided by “try with resources”. The try-with-resources is logically calling a finally block to close the reader. For ex:
try ( Reader reader = new BufferedReader(new FileReader(file))) {
// do something
} // Catch is not a must for try-with-resources, and is invoked just after code exists try
Java is a typed language and hence for using Try-with-resources, the class has to implement an Autocloseable or Closeable interface.
The difference between AutoCloseable and Closeable is that the former allows any Exception to be thrown while the latter allows only IOException.
TEST YOUR KNOWLEDGE
Q: What is the output for the following program?
What is the output for the below problem?
package com.jones.izo809;
public class Myutil {
public static void main(String[] args) {
Animal animal = new Dog();
Food food = new Flesh();
animal.eat(food);
}
}
class Food {
public String toString() {
return "Normal Food";
}
}
class Flesh extends Food {
public String toString() {
return "Flesh Food";
}
}
class Animal {
public void eat(Food food) {
System.out.println("Animal eats " + food);
}
}
class Dog extends Animal {
public void eat(Flesh flesh) {
System.out.println("Dog eats " + flesh);
}
}
You have made some good points there. I looked on the internet for additional information about the issue and found most people will go along with your views on this site.
Is getting a Masters Degree in Creative Writing a waste of time?