Nội dung bài viết
I. Access modifier
Mới đầu học java, mình không hiểu nổi vì sao phải có public, private, protected hay default (thường được gọi là package-private). Câu hỏi đó luẩn quẩn trong đầu mình mãi sau khi mình học java basic và code nhiều hơn, mình mới hiểu được ý tưởng của access modifier.
Ý tưởng của nó là “mỗi package/class là 1 black box, chỉ show cái gì cần thiết“
1. class
- Với class, chỉ có 2 access-modifier là public và default.
- Package 1 chỉ show class A ra bên ngoài vì class A là public, ý tưởng là class A là đầu mối giao tiếp. Do đó, các class của các package khác chỉ nhìn thấy và gọi được class A.
- class B là default, ý nghĩa là class B chỉ phục vụ cho các class khác trong package. Kiểu như nhân viên đằng sau cánh gà làm việc hùng hục chỉ để cho mấy ông ca sĩ xuất hiện trước sân khấu.
2. field
Với field, bạn có thể có public, default, protected và private.
- chỉ nên dùng private nếu không có yêu cầu gì đặc biệt
- dùng protected nếu bạn muốn class con của class đó thừa kế field đó
- dùng package-private, thường là vì lười viết, mình ko nghĩa ra lý do nào khác
- dùng public vì bạn chẳng hiểu access-modifier để làm gì
–> Chốt lại, với field mình luôn để private, field là để phục vụ method, ko phải để cho class khác lấy thông tin.
3. method
Tương tự, bạn cũng có 4 kiểu phân định access modifier cho method, tuy nhiên ý nghĩa sẽ khác.
- dùng public nếu bạn muốn đó là cách để class này giao tiếp với class khác
- dùng protected để nói rằng method này là mục đích thừa kế
- dùng package-private vì muốn method chỉ phục vụ riêng trong package.
- dùng private để method này chỉ phục vụ cho các method khác trong class
II. Static
Đôi khi bạn muốn viết những method mà muốn run nó sẽ không cần phải khởi tạo bất kỳ object nào cả. Đó chính là ý nghĩa của static.
Static có thể áp dụng cho method, field và block. Static field và static method đều thuộc về class nơi nó khai báo, không thuộc về bất cứ 1 instance nào cả. Do đó, các instance method có thể gọi static field và static method mà không có lỗi.
public class Example { public static String name = "test"; public static void test() {...} }
- biến
name
sẽ khởi tạo ngay khi class Example được load - để gọi method
test
bạn sẽ gọi theo syntax class_name.static_method, ví dụ:Example.test()
Khi nào bạn nên dùng static???
- Bạn dùng static field khi bạn muốn 1 thông tin nào đó là global acess, và nó thường là cố định không đổi.
public static final String USER_ADMIN = "admin";
- Bạn dùng static method khi bạn viết những method cho Utilities class. Cái này mình nói ở khóa học java intemediate.
III. Final
Khi bạn muốn biến của bạn không bị thay đổi sau khi có giá trị đầu tiên, thì sử dụng final.
Final có thể áp dụng với class, method và variables.
- Với final class, class con ko thể thừa kế được. ví dụ
public final class String
, bạn ko thể thừa kế class String. - Với final method, class con không thể override được.
Còn đối với variables thì có nhiều trường hợp khác nhau:
1. instance variables
Bạn sẽ có 2 cách để khởi tạo giá trị cho nó:
- Assign giá trị trực tiếp
- Assign giá trị thông qua constructor.
public class Example { public final String name = "test"; //assign trực tiếp private final int age; public Example (int age){ //assign qua constructor this.age = age; } }
Mục đích là để khi bạn khởi tạo 1 object, bạn muốn object đó có các field giữ nguyên giá trị từ lúc đẻ cho đến lúc chết. Nói đơn giản, không cho sửa thông tin trên giấy khai sinh.
2. Local variable
Bạn không muốn giá trị của biến bị thay đổi, mục đích là bạn không muốn dò xem value của cái biến này bị thay đổi ở chỗ nào khi debug.
public void print(){ final String name = "abc"; name = "xyz"; //compile error }
3. Parameter
- Nếu không có final
Ví dụ:
@Test void name() { List<Number> numbers = new ArrayList<>(List.of(1, 2, 42.1, 2)); print(numbers); // [5, 10, 20] } public void print (List<?> list) { list = List.of(5, 10, 20); System.out.println(list); }
List ban đầu bị biến đổi từ [1, 2, 42.1, 2]
–> [5, 10, 20]
- Nếu bạn thêm final vào thì nếu khi assign lại value cho
list
sẽ bị compile error. Ý tưởng của nó là tránh side effect, ai đó sử dụng và vô tình sửa cả giá trị ban đầu của tham số truyền vào, cái này áp dụng cho các parameter là reference type.
@Test void name() { List<Number> numbers = new ArrayList<>(List.of(1, 2, 42.1, 2)); print(numbers); } public void print (final List<?> list) { list = List.of(5, 10, 20); //compile error System.out.println(list); }
IV. Tổng kết
Trên đây là 1 vài keyword mà các bạn học java phải nắm rõ cả về cách sử dụng và ý tưởng của nó. Hi vọng bài viết có ích cho bạn, đừng quên 1 like cho người viết bài. Thanks