Access Modifiers trong Java được sử dụng để kiểm soát quyền truy cập trong chương trình Java. Java cung cấp cơ chế kiểm soát truy cập thông qua ba từ khóa chính: private, protected và public. Tuy nhiên, không phải lúc nào chúng ta cũng bắt buộc phải sử dụng các access modifier này. Trong trường hợp không khai báo rõ ràng bất kỳ modifier nào, Java sẽ sử dụng một loại mặc định gọi là “default access”, còn được biết đến với tên khác là “package-private” hoặc “no modifier”.

Java Access Modifiers
Chúng ta có thể sử dụng access modifiers trong Java không chỉ với lớp mà còn với biến và phương thức của lớp. Với lớp Java, chúng ta chỉ được phép sử dụng hai loại access modifier là “public” hoặc “default”.
- Nếu một lớp được khai báo là “public”, thì chúng ta có thể truy cập lớp đó từ bất kỳ đâu, tức là từ bất kỳ lớp nào, ở bất kỳ package nào.
- Trong một file mã nguồn Java, chỉ được phép có một lớp “public” duy nhất, và tên file phải trùng với tên lớp public đó.
- Nếu một lớp có “default access”, thì lớp đó chỉ có thể được truy cập từ các lớp khác trong cùng một package.
Access Modifiers với Thành viên lớp (Class Member)
Chúng ta có thể có tất cả bốn loại access modifiers cho các biến thành viên lớp và phương thức. Tuy nhiên, quy tắc kiểm soát truy cập của lớp sẽ được áp dụng trước khi xét đến quy tắc của các thành viên bên trong lớp. Ví dụ: nếu một lớp có default access, thì nó sẽ không thể truy cập được từ các package khác, và do đó, các phương thức và biến của lớp đó cũng sẽ không thể truy cập được từ bên ngoài package. Chúng ta sẽ lần lượt tìm hiểu chi tiết từng loại access modifier, sau đó sẽ minh hoạ cách sử dụng chúng trong một chương trình Java đơn giản.
Java Access Modifiers – từ khóa public
Nếu một thành viên trong lớp được khai báo là “public”, thì nó có thể được truy cập từ bất kỳ đâu. Biến thành viên hoặc phương thức public có thể được truy cập toàn cục. Đây là cách đơn giản nhất để cho phép truy cập đến các thành phần trong lớp. Tuy nhiên, chúng ta cần cẩn thận khi sử dụng từ khóa public với biến lớp, vì bất kỳ ai cũng có thể thay đổi giá trị. Thông thường, các biến trong lớp (class variables) được khai báo là private, và các phương thức getter và setter sẽ được cung cấp để làm việc với các biến đó.
Java Access Modifiers – từ khóa private
Nếu một class member được khai báo là “private”, thì nó chỉ có thể được truy cập bên trong chính lớp đó. Đây là mức truy cập bị giới hạn nhiều nhất, và thành viên này sẽ không hiển thị ra bên ngoài lớp. Thông thường, các biến trong lớp được khai báo là private, và các phương thức chỉ dùng nội bộ trong lớp cũng được đặt là private.
Java Access Modifiers – từ khóa protected
Nếu một thành viên lớp được khai báo là “protected”, thì nó chỉ có thể được truy cập bởi các lớp trong cùng một package và các lớp con (subclass). Modifier này ít bị giới hạn hơn private, nhưng vẫn hạn chế hơn so với public. Thông thường, chúng ta sử dụng từ khóa này để đảm bảo rằng các biến trong lớp chỉ có thể được truy cập bởi các lớp con.
Java Access Modifiers – default access
Nếu một thành viên trong lớp không được khai báo với bất kỳ access modifier nào, thì nó sẽ được xem là có default access. Quy tắc truy cập đối với default access tương tự như với lớp: thành viên đó chỉ có thể được truy cập bởi các lớp trong cùng một package. Kiểu truy cập này bị giới hạn nhiều hơn public và protected, nhưng ít bị hạn chế hơn private. (Ít tiếp cận nhất): private < default < protected < public (Dễ tiếp cận nhất) Bảng dưới đây sẽ tóm tắt các access modifiers ở trên khi xét đến các lớp trong cùng package, khác package, và các lớp con.

Hãy cùng viết một vài lớp đơn giản để quan sát cách các access modifiers trong Java hoạt động trong thực tế. Dưới đây là ví dụ với lớp TestA.java
package com.journaldev.access;
class TestA {
public void methodPublic(){
methodPrivate();
}
protected void methodProtected(){
methodPrivate();
}
void methodDefault(){
methodPrivate();
}
private void methodPrivate(){}
}
Lưu ý rằng lớp TestA có default access (truy cập mặc định), và phương thức private bên trong lớp chỉ có thể được truy cập trong chính lớp đó. TestB.java.
package com.journaldev.access;
import com.journaldev.access.TestA;
public class TestB {
public static void main(String args[]) {
new TestA().methodPublic();
new TestA().methodProtected();
new TestA().methodDefault();
}
public void methodPublic() {
}
protected void methodProtected() {
}
void methodDefault() {
}
private void methodPrivate() {
}
}
Lưu ý rằng TestB nằm trong cùng package với lớp TestA, do đó nó có thể truy cập các thành viên của lớp này. Các thành viên private không thể truy cập, nhưng tất cả các thành viên còn lại đều có thể truy cập được vì nằm trong cùng một package. TestC.java
package com.journaldev.access.child;
import com.journaldev.access.TestB;
public class TestC {
public static void main(String[] args) {
new TestB().methodPublic();
}
}
Lớp TestB có thể truy cập được vì nó là public. Tuy nhiên, chỉ các thành viên public của lớp TestB mới có thể truy cập được, vì lớp TestC không nằm trong cùng package và cũng không phải là lớp con của TestB. TestE.java
package com.journaldev.util;
import com.journaldev.access.TestB;
public class TestE extends TestB {
public static void main(String[] args) {
new TestB().methodPublic();
new TestB().methodProtected(); // compile time error
// works, accessing super class protected method using subclass
new TestE().methodProtected();
}
}
Vì lớp TestE là một lớp con của TestB, nên chúng ta có thể truy cập các thành viên protected của TestB thông qua lớp con TestE. Nếu cố gắng truy cập trực tiếp phương thức protected của lớp cha, chương trình sẽ báo lỗi biên dịch.
Vậy là bạn đã hoàn thành phần tìm hiểu về Java access modifiers. Bạn chỉ cần lưu ý đừng nhầm lẫn giữa default và protected. Một cách dễ nhớ là: default access bị hạn chế hơn protected, và các thành viên protected có thể được truy cập trong các lớp con.