Contents
Keyword
Java Keywords
In Java, keywords or reserved words are predefined terms that are used by the language for specific internal processes or actions. As such, these keywords cannot be used as variable names or identifiers; doing so will result in a compile-time error.
Example of Using Java Keywords as Variable Names
// Java Program to Illustrate the Consequences of Using Keywords as Variable Names
// Driver Class
class Example {
// Main Function
public static void main(String[] args) {
// Note "public" is a reserved word in Java
String public = "Hello, Java!";
System.out.println(public);
}
}
Output:
./Example.java:6: error: illegal start of expression
String public = "Hello, Java!";
^
1 error
Java Keywords List
Java contains a set of keywords that are typically highlighted in different colors in an IDE or editor to distinguish them from other words. Here’s a table summarizing the keywords and their associated actions:
Keyword | Usage |
---|---|
abstract | Specifies that a class or method will be implemented later in a subclass. |
assert | Indicates that a condition is assumed to be true at a specific point in the program. |
boolean | A data type that can hold true and false values. |
break | A control statement used to exit from loops or switch statements. |
byte | A data type that can hold 8-bit data values. |
case | Used in switch statements to define code blocks. |
catch | Handles exceptions thrown by try statements. |
char | A data type that can hold a single 16-bit Unicode character. |
class | Declares a new class. |
continue | Skips the current iteration of a loop and proceeds to the next iteration. |
default | Specifies the default block of code in a switch statement. |
do | Begins a do-while loop. |
double | A data type for 64-bit floating-point numbers. |
else | Specifies the alternative branch in an if statement. |
enum | Used to declare an enumerated type. |
extends | Indicates that a class is derived from another class or interface. |
final | Indicates that a variable holds a constant value or that a method cannot be overridden. |
finally | A block of code in a try-catch structure that will always execute. |
float | A data type for 32-bit floating-point numbers. |
for | Used to start a for loop. |
if | Tests a condition and executes code based on the result. |
implements | Specifies that a class implements an interface. |
import | References other classes or packages. |
instanceof | Checks whether an object is an instance of a specific class or implements an interface. |
int | A data type that can hold a 32-bit signed integer. |
interface | Declares an interface. |
long | A data type that can hold a 64-bit signed integer. |
native | Specifies that a method is implemented in platform-specific code. |
new | Creates new objects. |
null | Indicates that a reference does not point to any object. |
package | Declares a Java package. |
private | An access specifier that restricts access to the class where it is declared. |
protected | An access specifier that allows access to subclasses and classes in the same package. |
public | An access specifier that makes a class, method, or variable accessible throughout the application. |
return | Sends control and possibly a return value back from a called method. |
short | A data type that can hold a 16-bit signed integer. |
static | Indicates that a method or variable belongs to the class rather than an instance. |
strictfp | Ensures floating-point calculations follow strict rules for precision. |
super | Refers to the superclass of the current object. |
switch | A statement that executes code based on a specified value. |
synchronized | Indicates that a method or block is synchronized for thread safety. |
this | Refers to the current object within a method or constructor. |
throw | Used to explicitly throw an exception. |
throws | Specifies which exceptions a method can throw. |
transient | Indicates that a variable is not part of an object’s persistent state. |
try | Starts a block of code that will be tested for exceptions. |
void | Specifies that a method does not return a value. |
volatile | Indicates that a variable may be changed unexpectedly, used in multithreading. |
while | Starts a while loop. |
sealed | Declares a class that restricts which classes can extend it. |
permits | Used within a sealed class declaration to specify permitted subclasses. |
Important Notes on Java Keywords
The keywords const
and goto
are reserved for potential future use but are not currently utilized in Java.
- const: Reserved for future use.
- goto: Reserved for future use.
Important Keywords in Java
Keywords are a reserved set of words in a programming language that are used for specific predefined actions.
abstract: This non-access modifier is used for classes and methods to achieve abstraction. For more information, see the abstract keyword in Java.
enum: This keyword is used to define an enumeration in Java.
instanceof: This keyword checks whether an object is an instance of a specified type (class, subclass, or interface).
private: This access modifier restricts visibility; anything declared as private is not accessible outside its class.
protected: Use this keyword to allow access to an element outside of its package, but only to classes that directly subclass your class.
public: Anything declared as public can be accessed from anywhere in the application. For more information on access modifiers, refer to Access Modifiers in Java.
static: This keyword is used to create members (blocks, methods, variables, nested classes) that can be accessed without a reference to a specific instance. For more details, refer to the static keyword in Java.
strictfp: This keyword restricts floating-point calculations, ensuring consistent results across different platforms. For more information, refer to the strictfp keyword in Java.
synchronized: This keyword can be applied to methods or blocks to achieve synchronization in Java. For more details, see Synchronized in Java.
transient: This variable modifier is used during serialization. When we don’t want to save the value of a particular variable in a file during serialization, we use the transient keyword. For more information, refer to the transient keyword in Java.
volatile: The volatile modifier indicates to the compiler that the variable can be modified unexpectedly by other parts of the program. For more details, see the volatile keyword in Java.
Example Program Using Some Keywords
// Java Program to Demonstrate the Use of Various Keywords
// Abstract class definition
abstract class Animal {
abstract void sound(); // Abstract method
}
// Enum definition
enum Color {
RED, GREEN, BLUE
}
// Class implementing the abstract class
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
// Main class
public class KeywordExample {
// Static variable
static int count = 0;
// Synchronized method
synchronized void increment() {
count++;
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Outputs: Bark
Color myColor = Color.RED; // Using enum
System.out.println("Color: " + myColor); // Outputs: Color: RED
KeywordExample example = new KeywordExample();
example.increment();
System.out.println("Count: " + count); // Outputs: Count: 1
}
}
Output:
Bark
Color: RED
Count: 1
Super Keyword in Java
Characteristics of the super
Keyword in Java
In Java, the super
keyword is utilized to refer to the parent class of a subclass. Here are some key characteristics:
Calling Superclass Constructors: When a subclass is instantiated, its constructor must invoke the constructor of its parent class using
super()
.Calling Superclass Methods: A subclass can invoke a method defined in its parent class using the
super
keyword, which is helpful when the subclass wants to execute the parent class’s implementation of that method as well.Accessing Superclass Fields: A subclass can reference a field from its parent class using the
super
keyword. This is useful in cases where both the subclass and parent class have a field with the same name.Placement in Constructor: The
super()
statement must be the first line in the constructor of the subclass when invoking a superclass constructor.Static Context Restriction: The
super
keyword cannot be used in a static context, such as within static methods or static variable initializers.Optional Use for Method Calls: While the
super
keyword can be used to call a parent class method, it is not necessary if the method is not overridden in the subclass. In such cases, calling the method directly will invoke the parent class’s version.
Overall, the super
keyword is a powerful tool for subclassing in Java, allowing subclasses to inherit and extend the functionality of their parent classes.
Uses of the super
Keyword in Java
The super
keyword is primarily used in the following contexts:
1. Using super with Variables
2. Using super with Methods
3.Using super with Constructors
1. Using super
with Variables : This situation arises when both a derived class and its base class have identical data members, leading to potential ambiguity.
Example:
// Example of super keyword with variables
// Base class Animal
class Animal {
String type = "Mammal";
}
// Subclass Dog extending Animal
class Dog extends Animal {
String type = "Canine";
void display() {
// Print type from base class (Animal)
System.out.println("Animal Type: " + super.type);
}
}
// Driver Program
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.display();
}
}
Output:
Drawing a circle.
Drawing a shape.
In this example, both the base class and subclass have a member type
. The super
keyword allows us to access the type
variable of the base class.
2. Using super
with Methods : This usage occurs when we need to call a method from the parent class. If both the parent and child classes have methods with the same name, the super
keyword resolves ambiguity.
Example:
// Example of super keyword with methods
// Superclass Shape
class Shape {
void draw() {
System.out.println("Drawing a shape.");
}
}
// Subclass Circle extending Shape
class Circle extends Shape {
void draw() {
System.out.println("Drawing a circle.");
}
void display() {
// Calls the current class draw() method
draw();
// Calls the parent class draw() method
super.draw();
}
}
// Driver Program
public class Test {
public static void main(String[] args) {
Circle circle = new Circle();
circle.display();
}
}
In this example, when calling the draw()
method, the current class’s implementation is executed, but the super
keyword allows us to invoke the superclass’s method as well.
3. Using super
with Constructors : The super
keyword can also be employed to access the constructor of the parent class. It can call both parameterized and non-parameterized constructors, depending on the situation.
Example 1:
// Example of super keyword with constructors
// Superclass Animal
class Animal {
Animal() {
System.out.println("Animal class Constructor");
}
}
// Subclass Dog extending Animal
class Dog extends Animal {
Dog() {
// Invoke the parent class constructor
super();
System.out.println("Dog class Constructor");
}
}
// Driver Program
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
Output:
Animal class Constructor
Dog class Constructor
Advantages of Using the super
Keyword in Java
The super
keyword in Java offers several advantages in object-oriented programming:
Code Reusability: Using
super
allows subclasses to inherit functionality from their parent classes, promoting code reuse and reducing redundancy.Supports Polymorphism: Subclasses can override methods and access fields from their parent classes using
super
, enabling polymorphism and allowing for more flexible and extensible code.Access to Parent Class Behavior: Subclasses can utilize methods and fields defined in their parent classes through
super
, allowing them to leverage existing behavior without needing to reimplement it.Customization of Behavior: By overriding methods and using
super
to invoke the parent implementation, subclasses can customize and extend the behavior of their parent classes.Facilitates Abstraction and Encapsulation: The use of
super
promotes encapsulation and abstraction by allowing subclasses to focus on their own behavior while relying on the parent class to manage lower-level details.
final Keyword in Java
The final
keyword in Java is a non-access modifier that can be applied to variables, methods, or classes. It is used to impose restrictions on the element to which it is applied.
Key Uses of final
in Java:
1. Using super with Variables
2. Using super with Methods
3. Using super with Constructors
By exploring these uses in detail, the Java programming course allows developers to understand how and when to apply the final
keyword effectively.
Characteristics of final
in Java:
1. Final Variables: When a variable is declared as final, its value cannot be changed once it is initialized. This makes it ideal for defining constants.
2. Final Methods: Declaring a method as final prevents subclasses from modifying or overriding that method, ensuring its behavior is consistent.
3. Final Classes: A final class cannot be extended, meaning no other class can inherit from it. This is useful for creating classes that are intended to be used as-is.
4. Initialization of Final Variables: Final variables must be initialized when they are declared or in a constructor. If not, the program will not compile.
5. Performance: The use of final can sometimes improve performance, as the compiler optimizes final variables or methods better since their behavior is predictable.
6. Security: By making certain variables or methods final, you can prevent malicious code from altering critical parts of your program.
Example of final
Variable:
The final
keyword in Java is a non-access modifier that can be applied to variables, methods, or classes. It is used to impose restrictions on the element to which it is applied.
Key Uses of final
in Java:
1. Variables : A variable declared with final cannot have its value changed after initialization.
2. Methods : A method declared with final cannot be overridden by subclasses.
3. Classes: A class declared with final cannot be subclassed or extended.
By exploring these uses in detail, the Java programming course allows developers to understand how and when to apply the final
keyword effectively.
Characteristics of final
in Java:
1. Final Variables: When a variable is declared as final, its value cannot be changed once it is initialized. This makes it ideal for defining constants.
2. Final Methods: Declaring a method as final prevents subclasses from modifying or overriding that method, ensuring its behavior is consistent.
3. Final Classes: A final class cannot be extended, meaning no other class can inherit from it. This is useful for creating classes that are intended to be used as-is.
4. Initialization of Final Variables: Final variables must be initialized when they are declared or in a constructor. If not, the program will not compile.
5. Performance: The use of final can sometimes improve performance, as the compiler optimizes final variables or methods better since their behavior is predictable.
6. Security: By making certain variables or methods final, you can prevent malicious code from altering critical parts of your program.
Example of final
Variable:
public class Example {
public static void main(String[] args) {
// Declaring a final variable
final double CONSTANT = 3.14;
// Printing the value
System.out.println("Constant value: " + CONSTANT);
// Attempting to change the value would cause a compile-time error
// CONSTANT = 3.15;
}
}
Output:
Constant value: 3.14
Different Ways to Use final
Variable:
1. Final Variable Initialization at Declaration:
final int MAX_LIMIT = 100;
2. Blank Final Variable:
final int MAX_LIMIT; // Must be initialized later in the constructor
3. Static Final Variable:
static final double E = 2.718;
4. Static Blank Final Variable Initialized in Static Block:
static final int MAX_VALUE;
static {
MAX_VALUE = 999;
}
Initialization of Final Variables:
Final variables must be initialized either at declaration or inside constructors. The Java compiler ensures that once a final variable is initialized, it cannot be reassigned.
Example of Blank Final Variable:
class Demo {
final int THRESHOLD;
// Constructor to initialize blank final variable
public Demo(int value) {
this.THRESHOLD = value;
}
public static void main(String[] args) {
Demo demo = new Demo(10);
System.out.println("Threshold: " + demo.THRESHOLD);
}
}
Output:
Threshold: 10
Final Reference Variable (Non-Transitivity):
In the case of reference variables declared as final
, you can modify the internal state of the object, but the reference cannot be reassigned.
Example of Final Reference Variable:
class Example {
public static void main(String[] args) {
final StringBuilder message = new StringBuilder("Hello");
System.out.println(message);
// Modifying the internal state of the final object
message.append(", World!");
System.out.println(message);
// Reassigning the reference would cause a compile-time error
// message = new StringBuilder("Hi");
}
}
Output:
Hello
Hello, World!
Final Local Variable:
A final variable inside a method is called a local final variable. It can be initialized once, and any attempt to reassign it will result in an error.
class Example {
public static void main(String[] args) {
final int LIMIT;
LIMIT = 100; // Variable initialized
System.out.println("Limit: " + LIMIT);
// LIMIT = 200; // This line would cause a compile-time error
}
}
Output:
Limit: 100
Final Classes:
A class declared as final
cannot be extended by any subclass. This is useful when you want to ensure the class’s functionality remains intact and is not modified by other developers.
Example of Final Class:
final class Car {
void start() {
System.out.println("Car is starting");
}
}
// The following class would cause a compile-time error
// class SportsCar extends Car { }
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.start();
}
}
Output:
Car is starting
Final Methods:
When a method is declared as final
, it cannot be overridden by any subclass.
class Parent {
final void show() {
System.out.println("This is a final method.");
}
}
class Child extends Parent {
// The following method would cause a compile-time error
// void show() {
// System.out.println("Trying to override.");
// }
}
static Keyword in Java
The static
keyword in Java is primarily utilized for memory management. It allows variables or methods to be shared across all instances of a class. Users can apply the static
keyword to variables, methods, blocks, and nested classes. Unlike instance members, static members belong to the class itself rather than any particular instance, making them ideal for defining constants or methods that should remain consistent across all objects of the class.
Key Uses of static
in Java:
1. Blocks
2. Variables
3. Methods
4. Classes
Characteristics of the static
Keyword:
The static
keyword plays a crucial role in memory management by enabling class-level variables and methods. For a comprehensive understanding of how to effectively use static
, the Java Programming Course offers detailed explanations and practical examples. Here are some key characteristics of the static
keyword in Java:
Shared Memory Allocation: Static variables and methods are allocated memory space only once during the program’s execution. This shared memory space is accessible by all instances of the class, making static members ideal for maintaining global state or shared functionality.
Accessible Without Object Instantiation: Static members can be accessed without creating an instance of the class. This makes them useful for utility functions and constants that need to be accessible throughout the program.
Associated with the Class, Not Objects: Static members are tied to the class itself, not to individual objects. Therefore, any changes to a static member are reflected across all instances of the class. Static members can be accessed using the class name rather than an object reference.
Cannot Access Non-Static Members: Static methods and variables cannot directly access non-static members of a class because they are not associated with any particular instance of the class.
Can Be Overloaded, but Not Overridden: Static methods can be overloaded (multiple methods with the same name but different parameters), but they cannot be overridden since they are linked to the class rather than any instance.
Early Access: Static members can be accessed before any objects of the class are created and without referencing any object. For example, in the Java program below, the static method
displayMessage()
is called without creating an object of theUtility
class.
Example Program Accessing Static Method Without Object Creation
// Java program to demonstrate accessing a static method without creating an object
class Utility {
// Static method
static void displayMessage() {
System.out.println("Welcome to the Utility class!");
}
public static void main(String[] args) {
// Calling the static method without creating an instance of Utility
Utility.displayMessage();
}
}
Output:
Welcome to the Utility class!
Static Blocks
Static blocks are used for initializing static variables or executing code that needs to run once when the class is loaded. They are executed in the order they appear in the class.
Example of Static Block Usage
// Java program to demonstrate the use of static blocks
class Configuration {
// Static variables
static String appName;
static int version;
// Static block
static {
System.out.println("Initializing Configuration...");
appName = "MyApp";
version = 1;
}
public static void main(String[] args) {
System.out.println("Application Name: " + appName);
System.out.println("Version: " + version);
}
}
Output:
Initializing Configuration...
Application Name: MyApp
Version: 1
Static Variables
Static variables, also known as class variables, are shared among all instances of a class. They are typically used to store common properties or constants.
Important Points about Static Variables:
- Class-Level Scope: Static variables are declared at the class level and are shared by all instances.
- Initialization Order: Static blocks and static variables are executed in the order they appear in the program.
Example Demonstrating Static Variable Initialization Order
// Java program to demonstrate the initialization order of static blocks and variables
class InitializationDemo {
// Static variable initialized by a static method
static int initialValue = initialize();
// Static block
static {
System.out.println("Inside static block.");
}
// Static method
static int initialize() {
System.out.println("Initializing static variable.");
return 50;
}
public static void main(String[] args) {
System.out.println("Value of initialValue: " + initialValue);
System.out.println("Inside main method.");
}
}
Output:
Initializing static variable.
Inside static block.
Value of initialValue: 50
Inside main method.
Static Methods
Static methods belong to the class rather than any particular instance. The most common example of a static method is the main()
method. Static methods have several restrictions:
- They can only directly call other static methods.
- They can only directly access static data.
- They cannot refer to
this
orsuper
keywords.
Example Demonstrating Restrictions on Static Methods
// Java program to demonstrate restrictions on static methods
class Calculator {
// Static variable
static int total = 0;
// Instance variable
int count = 0;
// Static method
static void add(int value) {
total += value;
System.out.println("Total after addition: " + total);
// The following lines would cause compilation errors
// count += 1; // Error: non-static variable cannot be referenced from a static context
// displayCount(); // Error: non-static method cannot be referenced from a static context
}
// Instance method
void displayCount() {
System.out.println("Count: " + count);
}
public static void main(String[] args) {
Calculator.add(10);
Calculator.add(20);
}
}
Output:
Total after addition: 10
Total after addition: 30
When to Use Static Variables and Methods
Static Variables: Use static variables for properties that are common to all instances of a class. For example, if all students share the same school name, the school name can be a static variable.
Static Methods: Use static methods for operations that do not require data from instances of the class. Utility or helper methods that perform tasks independently of object state are ideal candidates for static methods.
Example Illustrating Static Variables and Methods
// Java program to demonstrate the use of static variables and methods
class School {
String studentName;
int studentId;
// Static variable for school name
static String schoolName;
// Static counter to assign unique IDs
static int idCounter = 1000;
public School(String name) {
this.studentName = name;
this.studentId = generateId();
}
// Static method to generate unique IDs
static int generateId() {
return idCounter++;
}
// Static method to set the school name
static void setSchoolName(String name) {
schoolName = name;
}
// Instance method to display student information
void displayInfo() {
System.out.println("Student Name: " + studentName);
System.out.println("Student ID: " + studentId);
System.out.println("School Name: " + schoolName);
System.out.println("--------------------------");
}
public static void main(String[] args) {
// Setting the static school name without creating an instance
School.setSchoolName("Greenwood High");
// Creating student instances
School student1 = new School("Emma");
School student2 = new School("Liam");
School student3 = new School("Olivia");
// Displaying student information
student1.displayInfo();
student2.displayInfo();
student3.displayInfo();
}
}
Output:
Student Name: Emma
Student ID: 1000
School Name: Greenwood High
--------------------------
Student Name: Liam
Student ID: 1001
School Name: Greenwood High
--------------------------
Student Name: Olivia
Student ID: 1002
School Name: Greenwood High
--------------------------
Static Classes (Nested Static Classes)
A class can be declared as static
only if it is a nested class. Top-level classes cannot be declared as static
. Static nested classes do not require a reference to an instance of the outer class and cannot access non-static members of the outer class.
Example of a Static Nested Class
// Java program to demonstrate the use of static nested classes
class OuterClass {
private static String outerMessage = "Hello from OuterClass!";
// Static nested class
static class NestedStaticClass {
void display() {
System.out.println(outerMessage);
}
}
public static void main(String[] args) {
// Creating an instance of the static nested class without an instance of OuterClass
OuterClass.NestedStaticClass nestedObj = new OuterClass.NestedStaticClass();
nestedObj.display();
}
}
Output:
Hello from OuterClass!
enum in Java
What is an Enum in Java?
In Java, Enum is a special data type used to define collections of constants. It allows you to represent a fixed set of predefined constants, such as the days of the week, the four seasons, etc. An enum is more than just a list of constants—it can contain methods, constructors, and variables, just like any other Java class.
Enums are particularly useful when you know all possible values at compile time and want to prevent invalid values from being used.
Key Properties of Enums
- Enum Constants: Each enum constant is an object of the enum type.
- Implicit Modifiers: Enum constants are
public
,static
, andfinal
. - Switch Compatibility: You can use enums with
switch
statements. - Constructor: An enum can contain a constructor that is invoked once for each constant.
- Method Support: Enums can have methods like regular classes, including abstract methods that must be implemented by each enum constant.
Enum Declaration in Java
Enums can be declared both inside or outside a class, but not inside a method.
1. Declaration Outside the Class
// Enum declared outside the class
enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
public class TestEnum {
public static void main(String[] args) {
Direction direction = Direction.NORTH;
System.out.println("The direction is: " + direction);
}
}
Output:
The direction is: NORTH
2. Declaration Inside the Class
// Enum declared inside a class
public class Weather {
enum Season {
SPRING,
SUMMER,
FALL,
WINTER
}
public static void main(String[] args) {
Season current = Season.WINTER;
System.out.println("The current season is: " + current);
}
}
Output:
The current season is: WINTER
Enum in Switch Statements
Enums can be used in switch
statements to handle different cases based on enum values.
// Enum in a switch statement
public class DaysOfWeek {
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
public static void main(String[] args) {
Day today = Day.FRIDAY;
switch (today) {
case MONDAY:
System.out.println("It's the start of the work week.");
break;
case FRIDAY:
System.out.println("Almost the weekend!");
break;
case SATURDAY:
case SUNDAY:
System.out.println("It's the weekend!");
break;
default:
System.out.println("It's a regular workday.");
}
}
}
Output:
Almost the weekend!
Looping Through Enum Constants
You can iterate over the constants in an enum using the values()
method, which returns an array of all enum constants.
// Looping through enum constants
public class ColorExample {
enum Color {
RED, GREEN, BLUE, YELLOW
}
public static void main(String[] args) {
for (Color color : Color.values()) {
System.out.println("Color: " + color);
}
}
}
Output:
Color: RED
Color: GREEN
Color: BLUE
Color: YELLOW
Enum with Constructor and Method
Enums can contain constructors and methods, making them more powerful than just simple constants.
// Enum with constructor and method
public class CarTypeExample {
enum CarType {
SEDAN(4), SUV(6), TRUCK(8);
private int seats;
// Enum constructor
CarType(int seats) {
this.seats = seats;
}
public int getSeats() {
return seats;
}
}
public static void main(String[] args) {
CarType myCar = CarType.SUV;
System.out.println("My car type is: " + myCar + " with " + myCar.getSeats() + " seats.");
}
}
Output:
My car type is: SUV with 6 seats.
Enum with Abstract Methods
Enums can also contain abstract methods that each constant must implement.
// Enum with abstract method
public class PlanetExample {
enum Planet {
MERCURY {
public String getOrbitalPeriod() {
return "88 days";
}
},
EARTH {
public String getOrbitalPeriod() {
return "365 days";
}
},
MARS {
public String getOrbitalPeriod() {
return "687 days";
}
};
public abstract String getOrbitalPeriod();
}
public static void main(String[] args) {
Planet planet = Planet.EARTH;
System.out.println("The orbital period of " + planet + " is " + planet.getOrbitalPeriod());
}
}
Output:
// Using EnumSet to iterate over a specific range of enum values
import java.util.EnumSet;
public class DaysRangeExample {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public static void main(String[] args) {
EnumSet workdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
for (Day day : workdays) {
System.out.println("Workday: " + day);
}
}
}
Output:
The orbital period of EARTH is 365 days
transient keyword in Java
The transient
keyword in Java is used to indicate that a particular field should not be serialized when the object is written to a stream. During serialization, if a field is marked as transient
, its value is not saved, and when the object is deserialized, that field is assigned its default value according to its data type.
The transient
keyword is especially useful for sensitive data that you don’t want to store, such as passwords or fields that can be recalculated at runtime, such as a person’s age or a timestamp.
Usage of transient
Keyword
When an object is serialized, all its fields are saved unless they are marked with the transient
modifier. If a field is marked as transient
, it is skipped during the serialization process, and its value will be reset to the default when the object is deserialized.
This is often used to protect sensitive data, such as passwords, or for fields that can be derived from other fields.
Example of transient
Keyword:
// A simple class to demonstrate the use of the transient keyword
import java.io.*;
class Example implements Serializable {
// Regular fields
private String username;
private String email;
// Password field marked as transient for security
private transient String password;
// Age field marked as transient because it can be recalculated
transient int age;
// Constructor
public Example(String username, String email, String password, int age) {
this.username = username;
this.email = email;
this.password = password;
this.age = age;
}
// Display user information
public void displayInfo() {
System.out.println("Username: " + username);
System.out.println("Email: " + email);
System.out.println("Password: " + password);
System.out.println("Age: " + age);
}
}
public class TestTransient {
public static void main(String[] args) throws Exception {
// Create an instance of the class
Example user = new Example("JohnDoe", "john@example.com", "secretPassword", 30);
// Serialization process
FileOutputStream fileOut = new FileOutputStream("user_data.txt");
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(user);
objectOut.close();
fileOut.close();
// Deserialization process
FileInputStream fileIn = new FileInputStream("user_data.txt");
ObjectInputStream objectIn = new ObjectInputStream(fileIn);
Example deserializedUser = (Example) objectIn.readObject();
objectIn.close();
fileIn.close();
// Display the deserialized object's info
System.out.println("After Deserialization:");
deserializedUser.displayInfo();
}
}
Output:
Username: JohnDoe
Email: john@example.com
Password: null
Age: 0
In this example:
- The
password
andage
fields are marked astransient
, so they are not serialized. - When deserialized, the
password
field becomesnull
, and theage
field is set to0
(the default value for integers).
transient
and static
Fields
The transient
keyword has no effect on static
fields because static fields are not serialized as part of the object state. Similarly, marking a static
field as transient
has no impact, as static
variables belong to the class and not the instance.
Example with static
and final
Fields:
// A simple class to demonstrate transient with static and final variables
import java.io.*;
class TestStaticFinal implements Serializable {
// Regular fields
int x = 100, y = 200;
// Transient field
transient int z = 300;
// Transient has no effect on static variables
transient static int a = 400;
// Transient has no effect on final variables
transient final int b = 500;
public static void main(String[] args) throws Exception {
TestStaticFinal object = new TestStaticFinal();
// Serialize the object
FileOutputStream fos = new FileOutputStream("static_final.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
fos.close();
// Deserialize the object
FileInputStream fis = new FileInputStream("static_final.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
TestStaticFinal deserializedObject = (TestStaticFinal) ois.readObject();
ois.close();
fis.close();
// Display the values after deserialization
System.out.println("x = " + deserializedObject.x);
System.out.println("y = " + deserializedObject.y);
System.out.println("z = " + deserializedObject.z); // Will be 0 (default value)
System.out.println("a = " + TestStaticFinal.a); // Will be 400
System.out.println("b = " + deserializedObject.b); // Will be 500
}
}
Output:
x = 100
y = 200
z = 0
a = 400
b = 500
volatile Keyword
The volatile
keyword in Java is used to ensure that updates to a variable are immediately visible to all threads. This is essential in a multithreaded environment to prevent inconsistencies due to threads caching variable values locally, which can lead to stale data being used. Let’s consider an example to better understand its behavior.
Problem Without volatile
:
When multiple threads are operating on the same variable, they may maintain a local copy of the variable in their own cache. Changes made by one thread may not be immediately visible to the other threads, leading to unpredictable results.
For instance:
class SharedResource {
// Without volatile, changes made by one thread
// may not reflect immediately in others.
static int sharedValue = 10;
}
With volatile
, the sharedValue
is always read from the main memory and never from the thread’s cache, ensuring that all threads have the most up-to-date value.
Difference Between volatile
and synchronized
:
- Mutual Exclusion: The
synchronized
keyword ensures that only one thread can access a critical section of code at any time. - Visibility: Both
volatile
andsynchronized
ensure that changes made by one thread are visible to other threads.
However, if you only need to ensure visibility and don’t require atomic operations (such as incrementing), volatile
can be used to avoid the overhead of synchronization.
Example Using volatile
:
// Java program to demonstrate the use of volatile keyword
public class VolatileDemo {
private static volatile int counter = 0;
public static void main(String[] args) {
new UpdateThread().start();
new MonitorThread().start();
}
// Thread that monitors changes to the volatile variable
static class MonitorThread extends Thread {
@Override
public void run() {
int localCounter = counter;
while (localCounter < 5) {
if (localCounter != counter) {
System.out.println("Detected change in counter: " + counter);
localCounter = counter;
}
}
}
}
// Thread that updates the volatile variable
static class UpdateThread extends Thread {
@Override
public void run() {
int localCounter = counter;
while (counter < 5) {
System.out.println("Incrementing counter to " + (localCounter + 1));
counter = ++localCounter;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Output (With volatile
):
Incrementing counter to 1
Detected change in counter: 1
Incrementing counter to 2
Detected change in counter: 2
Incrementing counter to 3
Detected change in counter: 3
Incrementing counter to 4
Detected change in counter: 4
Incrementing counter to 5
Detected change in counter: 5
Output (Without volatile
):
Incrementing counter to 1
Incrementing counter to 2
Incrementing counter to 3
Incrementing counter to 4
Incrementing counter to 5
final, finally and finalize in Java
final
Keyword in Java
In Java, final
is a reserved keyword, meaning we cannot use it as an identifier (variable name, method name, etc.). It serves distinct purposes depending on where it is applied — whether to variables, methods, or classes.
1. final
with Variables
When a variable is declared as final
, its value cannot be modified once initialized. Any attempt to change its value will result in a compile-time error.
class Example1 {
public static void main(String[] args) {
// Non-final variable
int x = 10;
// Final variable
final int y = 20;
// Modifying non-final variable: Allowed
x++;
// Modifying final variable: Gives a compile-time error
y++; // Error: Cannot assign a value to a final variable 'y'
}
}
Here, attempting to modify the value of the final
variable y
will cause a compile-time error.
2. final
with Classes
If a class is declared final
, it cannot be subclassed. In other words, no class can extend a final
class.
final class SuperClass {
public void display() {
System.out.println("This is a final class.");
}
}
// The following class will cause a compile-time error as `SuperClass` is final and cannot be extended
class SubClass extends SuperClass {
// Compile-time error: Cannot inherit from final 'SuperClass'
}
3. final
with Methods
When a method is declared as final
, it cannot be overridden by subclasses.
class ParentClass {
final void show() {
System.out.println("Final method in the parent class.");
}
}
class ChildClass extends ParentClass {
// The following method will cause a compile-time error
void show() {
// Compile-time error: Cannot override the final method from 'ParentClass'
System.out.println("Trying to override the final method.");
}
}
In this case, the subclass ChildClass
cannot override the final
method show()
from ParentClass
.
Note: final
with Classes and Methods
If a class is declared final
, all its methods are implicitly final
by default. However, its variables are not.
final class FinalClass {
// Method is final by default
void display() {
System.out.println("Final class method.");
}
// Static variables can still be modified
static int value = 50;
public static void main(String[] args) {
// Modifying the static variable
value = 60;
System.out.println("Value: " + value); // Output: 60
}
}
finally
Keyword
The finally
keyword is associated with try
and catch
blocks. It ensures that a block of code will always be executed, regardless of whether an exception occurs or not. The finally
block is generally used for cleanup operations like closing resources (e.g., file handles, database connections).
Example: finally
with Exception Handling
class ExampleFinally {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
throw new RuntimeException("Exception in try");
} finally {
System.out.println("Finally block always executes");
}
}
}
In this example, even though an exception is thrown, the finally
block still executes.
Cases Involving finally
Block:
Case 1: No Exception Occurs
class NoException {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
int result = 10 / 2;
} finally {
System.out.println("Finally block executed");
}
}
}
Output:
Inside try block
Finally block executed
Here, no exception occurs, but the finally
block still executes.
Case 2: Exception Occurs and is Caught
class CatchException {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Caught ArithmeticException");
} finally {
System.out.println("Finally block executed");
}
}
}
Output:
Inside try block
Caught ArithmeticException
Finally block executed
Case 3: Exception Occurs but No Catch Block
class NoCatchBlock {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
int result = 10 / 0;
} finally {
System.out.println("Finally block executed");
}
}
}
Output:
Inside try block
Finally block executed
Exception in thread "main" java.lang.ArithmeticException: / by zero
Case 4: System.exit(0)
in try
Block
class ExitExample {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
System.exit(0);
} finally {
System.out.println("Finally block not executed");
}
}
}
Output:
Inside try block
Finalize Method
The finalize
method is called by the garbage collector just before an object is destroyed. It is meant for resource cleanup before an object is deleted.
Example: Garbage Collector Calling finalize
class GarbageCollectorExample {
public static void main(String[] args) {
GarbageCollectorExample obj = new GarbageCollectorExample();
obj = null;
System.gc();
System.out.println("Main method ends");
}
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize method called");
}
}
Output:
Main method ends
Finalize method called