Set 1
Why main method is always declared with public static void?
In Java, public static void main(String[] args) is the entry point of any Java program. L
public: It means that themainmethod can be accessed from anywhere. It's necessary because the Java Virtual Machine (JVM) needs to access this method to start the execution of the program.static: It means that themainmethod belongs to the class itself, rather than to any instance of the class. This is because Java starts the program before any objects are created.void: It indicates that themainmethod doesn't return any value.main: This is the name of the method.mainis a special method name recognized by the JVM.(String[] args): This is the parameter thatmainaccepts.argsis an array of strings that can be passed to the program from the command line. These are typically arguments that you want to pass to your program when you run it.
So, when we run a Java program from the command line, we can pass arguments to it like this. args will contain ["arg1", "arg2", "arg3"], and we can access these values inside the main method.
java SomeClassName arg1 arg2 arg3Java Interfaces and abstract classes
Interfaces and abstract classes are both tools for achieving abstraction in Java, but they serve different purposes.
Use Interfaces When
Defining a Contract: Interfaces are used to define a contract or a set of methods that a class must implement. They specify what a class can do, without providing any implementation details.
Multiple Inheritance of Type: Java doesn't support multiple inheritance of classes, but it does support implementing multiple interfaces. This makes interfaces useful when a class needs to inherit behavior from multiple sources.
Loose Coupling: Interfaces promote loose coupling between components by providing a common abstraction. Classes can interact through interfaces without being tightly bound to each other's implementations.
API Design: Interfaces are often used in API design to define a set of methods that other classes must implement. This allows for flexibility and extensibility in the implementation details.
Use Abstract Classes When
Partial Implementation: Abstract classes can provide partial implementations of methods, along with abstract methods that must be implemented by subclasses. This is useful when you have a base class that contains common behavior shared by multiple subclasses.
Code Reusability: Abstract classes allow you to define common behavior once and reuse it across multiple subclasses. They can contain fields, constructors, and methods that are shared among subclasses.
Stronger Encapsulation: Abstract classes can have member variables with different access modifiers (e.g., private, protected), providing stronger encapsulation compared to interfaces, which can only have public members.
Evolution Over Time: Abstract classes provide more flexibility for evolving the API over time. You can add new methods (abstract or concrete) to an abstract class without breaking existing implementations, whereas adding new methods to an interface requires modifying all implementing classes.
Example of Interface
The Comparable interface in Java is a good example. It's used to define a contract for classes that can be compared to each other. Classes that implement Comparable must provide an implementation for the compareTo method, which compares the object with another object of the same type and returns an integer indicating the comparison result. For example, the String class implements Comparable
Example of Abstract Class
Creating an abstract class Shape to represent common behavior and characteristics of all different shapes. It provides common functionality like printDetails()
Example using both interface and abstract class
Consider an example of payment processing system. PaymentProcessor interface defines a contract. Any class implementing PaymentProcessor must have a processPayment method that takes an amount and returns true if the payment is successful. AbstractPaymentGateway abstract class extends the PaymentProcessor interface and provides some common functionalities:
Statically Typed (like Java) and Dynamically Typed Languages
Statically Typed Languages (like Java):
Type declaration at compile time: We explicitly declare the data type (e.g.,
int,String) of a variable when we define it.Compile-time type checking: The compiler verifies if the assigned values match the declared data type during compilation. This helps catch errors early on.
Strong type safety: Variables can only hold values of their declared type, preventing unexpected behavior at runtime.
Dynamically Typed Languages:
Type inferred at runtime: The data type of a variable is determined by the value assigned to it at runtime, not by explicit declaration.
Runtime type checking: Type checking happens during program execution, not before. This offers more flexibility but can lead to runtime errors if incorrect types are used.
Weaker type safety: Variables can hold different data types throughout the program, potentially causing issues if not handled carefully.
final keyword on field, method and class
final keyword on field, method and classThe final keyword in Java is used to restrict modifications or inheritance. Here's a breakdown of its meaning when applied to fields (variables), methods, and classes:
Final Field (Variable):
When a field (variable) is declared as
final, its value cannot be changed after it's initialized. This ensures the value remains constant throughout the program.Example:
Final Method:
When a method is declared as
final, it cannot be overridden by subclasses. This prevents subclasses from modifying the behavior of that specific method.Example:
Final Class:
When a class is declared as
final, it cannot be extended or subclassed. This means you cannot create new classes that inherit from the final class.Example:
When to Use final:
final:Consider using final when:
We want to ensure a variable's value remains constant.
We want to prevent method overrides in subclasses (for specific well-defined behaviors).
We have a class that serves a utility purpose and doesn't need subclasses.
By understanding the meaning of final with fields, methods, and classes, we can effectively control mutability, inheritance, and code structure in Java programs.
transient keyword in java
transient keyword in javaThe transient keyword in Java is used specifically in the context of serialization. Serialization is the process of converting an object's state into a stream of bytes that can be stored or transmitted. Deserialization is the opposite process of recreating an object from a byte stream. Transient fields are initialized to their default values during deserialization.
Here's how the transient keyword affects serialization:
Purpose:
When we declare a field (variable) of a class as
transient, its value will not be serialized when the object is serialized.This is useful for data members that don't represent the essential state of the object or that can be easily recalculated during deserialization. Or when we have fields that do not need to be saved or transferred along with the object's state.
Example:
Ways to provide default value if a variable is null ?
1. Ternary Operator
Syntax:
Example:
2. Objects.requireNonNullElse (Java 9+)
Syntax:
Example:
Returns the first argument if it's non-null; otherwise returns the second.
Safe and expressive alternative to ternary.
3. Objects.requireNonNullElseGet (Java 9+)
Syntax:
Lazily computes the default value only if needed.
Useful when default is expensive to calculate.
4. Optional.ofNullable(...).orElse(...) (Java 8+)
Syntax:
Example:
Avoids manual null checks.
Slightly more verbose but readable.
Avoid for primitive types in performance-critical code.
5. Manual if Condition
Example:
Simple and clear.
Preferred in older codebases or when mutation is needed.
Last updated