Java Modifiers: Access and Behavior Contro
Modifiers in Java are keywords that define the accessibility, behavior, and properties of classes, methods, and variables. Java modifiers can be broadly categorized into access modifiers and non-access modifiers. Access modifiers define the visibility of classes, methods, and variables, while non-access modifiers provide additional properties like immutability, synchronization, or the ability to override behaviors.
Understanding Java modifiers is crucial, as they help you encapsulate data, control access, and add specific functionalities to your code.
Types of Modifiers in Java
Modifiers in Java are divided into two main categories:
- Access Modifiers
- Control the visibility of classes, methods, and variables.
- Types:
public
,protected
,default
(no keyword),private
.
- Non-Access Modifiers
- Control specific properties or behavior.
- Types:
static
,final
,abstract
,synchronized
,transient
,volatile
.
Let’s explore each type in detail.
1. Access Modifiers
Access modifiers determine the visibility of a class, method, or variable. There are four access modifiers in Java:
Modifier | Class | Package | Subclass | World |
---|---|---|---|---|
public | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | No |
(default) | Yes | Yes | No | No |
private | Yes | No | No | No |
public
Access Modifier
- Class-Level: The class is accessible from any other class in the program.
- Method/Variable-Level: The variable or method can be accessed from any class.
Example of public
Modifier:
public class Car {
public String brand;
public void displayBrand() {
System.out.println("Brand: " + brand);
}
}
private
Access Modifier
- Class-Level: Not allowed on top-level classes.
- Method/Variable-Level: The variable or method can only be accessed within the class it is declared in.
Example of private
Modifier:
public class Car {
private String engineNumber;
private void showEngineNumber() {
System.out.println("Engine Number: " + engineNumber);
}
}
protected
Access Modifier
- Class-Level: Not allowed on top-level classes.
- Method/Variable-Level: The variable or method can be accessed within the same package or by subclasses.
Example of protected
Modifier:
public class Vehicle {
protected String model;
protected void displayModel() {
System.out.println("Model: " + model);
}
}
Default (Package-Private) Access Modifier
- If no access modifier is specified, the class, method, or variable is only accessible within the same package.
Example of Default Access Modifier:
class Bike {
String color; // package-private access
void displayColor() {
System.out.println("Color: " + color);
}
}
2. Non-Access Modifiers
Non-access modifiers control additional properties and behaviors.
static
Modifier
- Method/Variable-Level: Belongs to the class rather than to any specific instance.
- Usage: To define class-level variables and methods.
Example of static
Modifier:
public class Car {
public static int totalCars = 0;
public static void displayTotalCars() {
System.out.println("Total Cars: " + totalCars);
}
}
final
Modifier
- Class-Level: Prevents the class from being subclassed.
- Method-Level: Prevents the method from being overridden.
- Variable-Level: Prevents the variable from being changed after it’s initialized (makes it a constant).
Example of final
Modifier:
public final class Car {
public final int maxSpeed = 200;
public final void showMaxSpeed() {
System.out.println("Max Speed: " + maxSpeed);
}
}
abstract
Modifier
- Class-Level: Defines an abstract class that cannot be instantiated.
- Method-Level: Defines an abstract method that must be implemented in subclasses.
Example of abstract
Modifier:
public abstract class Vehicle {
public abstract void drive(); // No implementation here
}
public class Car extends Vehicle {
public void drive() {
System.out.println("Driving the car.");
}
}
synchronized
Modifier
- Method/Block-Level: Ensures that only one thread can execute the method or block at a time.
Example of synchronized
Modifier:
public class BankAccount {
private double balance;
public synchronized void deposit(double amount) {
balance += amount;
}
}
transient
Modifier
- Variable-Level: Prevents the serialization of certain variables, so they are not included in serialized objects.
Example of transient
Modifier:
public class User {
public String username;
public transient String password; // Will not be serialized
}
volatile
Modifier
- Variable-Level: Indicates that a variable’s value may change asynchronously, ensuring that all threads see the latest value.
Example of volatile
Modifier:
public class SharedResource {
public volatile boolean isActive;
}
Exercises
Let’s practice using modifiers through the following exercises.
Exercise 1: Access Modifiers in a BankAccount Class
- Create a
BankAccount
class with attributesaccountNumber
(String) andbalance
(double). - Use
private
for both attributes. - Add a
public
methoddeposit(double amount)
to add to the balance andpublic
methodwithdraw(double amount)
to subtract from the balance if funds are sufficient. - Add a
public
methodgetBalance()
to return the current balance. - Create a
BankAccount
object and test the methods.
Expected Outcome: You should only be able to access the deposit
, withdraw
, and getBalance
methods, not the accountNumber
and balance
directly.
Exercise 2: Using static
Modifier in a Library Class
- Create a
Library
class with:
- A
static
variabletotalBooks
(int) to keep track of the total number of books. - An instance variable
bookTitle
(String) to hold the book’s title.
- Create a constructor that increments
totalBooks
by 1 each time a new book is added. - Add a
static
methoddisplayTotalBooks()
to display the total number of books. - Create multiple
Library
objects and calldisplayTotalBooks()
.
Expected Outcome: The total book count should increase each time a new book is created, and displayTotalBooks()
should reflect the correct total.
Exercise 3: Working with final
Modifier in a Vehicle Class
- Create a
Vehicle
class with:
- A
final
variableMAX_SPEED
(int) set to120
. - A
final
methodshowMaxSpeed()
that displaysMAX_SPEED
.
- Create a subclass
Car
that inherits fromVehicle
. - Try to override
showMaxSpeed()
inCar
and observe the error. - In
Vehicle
, add apublic
methoddrive()
and override it inCar
.
Expected Outcome: You should see that MAX_SPEED
and showMaxSpeed()
cannot be modified or overridden.
Exercise 4: Creating Abstract Class for Shapes
- Create an abstract class
Shape
with an abstract methodcalculateArea()
. - Create subclasses
Circle
andRectangle
that implementcalculateArea()
. - In
Circle
, accept a radius, and inRectangle
, accept length and width. - Test the area calculation for each shape by creating objects of
Circle
andRectangle
.
Expected Outcome: Each subclass should correctly implement calculateArea()
, demonstrating the use of abstract classes.
Exercise 5: Using transient
Modifier in User Class
- Create a
User
class with:
- A
String
attributeusername
. - A
transient
String
attributepassword
.
- Serialize and deserialize a
User
object and observe that thepassword
field is not preserved.
Expected Outcome: The password
field should be null after deserialization, demonstrating the effect of the transient
modifier.
Exercise 6: Volatile and Synchronized Modifiers for Multi-threading
- Create a
Counter
class with:
- A
volatile
boolean
attributeactive
set totrue
. - A synchronized method
increment()
that increases acount
by 1 whileactive
is true.
- Start a thread that increments the count.
- Create a second thread to change
active
tofalse
after a delay.
Expected Outcome: The count should stop increasing when active
is set to false, showing the effect of volatile
and synchronized
.
Conclusion
Modifiers in Java offer powerful ways to control access, behavior, and properties of classes, methods, and variables. Access modifiers (public
, private
, protected
, default) control visibility, while non-access modifiers (static
, final
, abstract
, synchronized
, transient
, volatile
) manage various properties like immutability, inheritance control, and thread safety. Through exercises, you can gain a strong grasp of using modifiers effectively to improve code structure, security, and efficiency.
Happy coding!