1. Thuộc tính static của lớp trong Java
Trong Java, khi khai báo và định nghĩa lớp (class), các thuộc tính được khai báo với từ khóa static gọi là thuộc tính tĩnh (static). Đặc điểm của thuộc tính này là nó thuộc về lớp chứ không phải thuộc về từng đối tượng của lớp.
Khi khởi tạo đối tượng của lớp thì mỗi đối tượng được cấp một vùng nhớ riêng để lưu trữ những thuộc tính dữ liệu của nó. Nhưng với thuộc tính static thì tất cả các đối tượng của lớp sử dụng chung thuộc tính này.
Một đối tượng của lớp thay đổi giá trị của thuộc tính static thì các đối tượng khác của lớp cũng nhận sự thay đổi của thuộc tính static này.
Cú pháp khai báo thuộc tính static:
accessmodifier static <kiểudữliệu> tênthuộctính;
Ví dụ:
class Main {
public static int iStatic;//thuộc tính static
public int iNonStatic;//thuộc tính không phải static
public static void main(String[] args) {
Main obj1 = new Main();
obj1.iStatic = 10;
obj1.iNonStatic = 11;
Main obj2 = new Main();
System.out.println("obj1.iStatic=" + obj1.iStatic + ", obj1.iNonStatic=" + obj1.iNonStatic);
System.out.println("obj2.iStatic=" + obj2.iStatic + ", obj2.iNonStatic=" + obj2.iNonStatic);
obj1.iNonStatic = 111;
obj2.iNonStatic = 999;
obj2.iStatic = -555;
System.out.println("obj1.iStatic=" + obj1.iStatic + ", obj1.iNonStatic=" + obj1.iNonStatic);
System.out.println("obj2.iStatic=" + obj2.iStatic + ", obj2.iNonStatic=" + obj2.iNonStatic);
}
}
Kết quả
obj1.iStatic=10, obj1.iNonStatic=11
obj2.iStatic=10, obj2.iNonStatic=0
obj1.iStatic=-555, obj1.iNonStatic=111
obj2.iStatic=-555, obj2.iNonStatic=999
Rõ ràng, thuộc tính static iStatic được truy xuất từ obj1 và obj2 là như nhau bởi chúng sử dụng chung từ lớp Main.
Lưu ý: Thuộc tính static có thể được truy cập trực tiếp bởi tên lớp mà không cần khởi tạo đối tượng để gọi.
class Main {
public static int iStatic;//thuộc tính static
public static void main(String[] args) {
Main.iStatic = 5;//truy cập biến static bằng tên lớp Main
Main obj1 = new Main();
System.out.println(obj1.iStatic);
}
}
Kết quả
obj1.iStatic = 5
2. Phương thức static của lớp trong Java
Các phương thức static của lớp là các phương thức được khai báo với từ khóa static. Gọi phương thức static với tên lớp, không cần khởi tạo đối tượng để gọi phương thức static.
Các phương thức static chỉ có thể truy cập vào các thuộc tính static và chỉ có thể gọi các phương thức static trong cùng một lớp.
class MyUtils {
public static double mean(int[] p) {
int sum = 0;
for (int i = 0; i < p.length; i++) {
sum += p[i];
}
return ((double)sum) / p.length;
}
}
class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
// Gọi phương thức tĩnh
double avgAtt = MyUtils.mean(arr);
System.out.print(avgAtt);
}
}
Thành viên lớp và thành viên đối tượng trong Java
Thành viên đối tượng | Thành viên lớp (static) |
Thuộc tính/phương thức chỉ được truy cập thông qua đối tượng. | Thuộc tính/phương thức có thể được truy cập thông qua lớp. |
Mỗi đối tượng có một bản sao riêng của một thuộc tính. | Các đối tượng có chung một bản sao của một thuộc tính. |
Giá trị của một thuộc tính của các đối tượng khác nhau là khác nhau. | Giá trị của một thuộc tính của các đối tượng khác nhau là giống nhau. |
3. Khối lệnh static trong Java
Khối lệnh static bắt đầu với từ khóa static. Được sử dụng để khởi tạo thành viên dữ liệu static. Nó được thực thi trước phương thức main()
tại lúc tải lớp.
class Main {
static int x;
static {
x = 10;
System.out.println("Khoi static!");
}
public static void main(String[] args) {
Main obj = new Main();
System.out.println("obj.x=" + obj.x);
System.out.println("Ham main!");
}
}
Kết quả
Khoi static!
obj.x=10
Ham main!
4. Thuộc tính final của lớp trong Java
Thuộc tính của lớp có thể là một hằng số. Sử dụng từ khóa final để khai báo thuộc tính final.
<accessmodifier> final <kiểudữliệu> tênhằng = giá trị;
import java.util.Arrays;
class Main {
final double PI = 3.141592653589793;
public final int VAL_THREE = 39;
private final int[] A = { 1, 2, 3, 4, 5, 6 };
public static void main(String[] args) {
Main obj = new Main();
System.out.println(obj.PI);
System.out.println(obj.VAL_THREE);
System.out.println(Arrays.toString(obj.A));
}
}
Kết quả
3.141592653589793
39
[1, 2, 3, 4, 5, 6]
5. Biến final trống là gì?
Biến final không khởi tạo tại thời điểm khai báo được gọi là biến final trống. Nhưng biến final trống phải được khởi tạo trong hàm constructor của lớp.
class Main {
final double PI;
public Main() {
PI = 3.14;
}
public static void main(String[] args) {
Main obj = new Main();
System.out.println(obj.PI);
}
}
6. Phương thức final trong Java
Trong Java, không thể ghi đè phương thức final. Ghi đè (overriding) là trường hợp phương thức của lớp cha được định nghĩa lại trong lớp con khi kế thừa.
class Bike {
final void run() {
System.out.println("Running!");
}
}
public class Honda extends Bike {
@Override
void run() { System.out.println("Toc do 80Km/h!"); }
public static void main(String args[]) {
Honda xeLead = new Honda ();
xeLead.run();
}
}
Kết quả
java.lang.VerifyError: class Honda overrides final method run.()
7. Lớp final trong Java
Trong Java, không thể kế thừa lớp final.
final class Bike {
final void run() {
System.out.println("Running!");
}
}
public class Honda extends Bike {
public static void main(String args[]) {
Honda xeLead = new Honda ();
xeLead.run();
}
}
Kết quả
java.lang.VerifyError: Cannot inherit from final class
8. Các thành viên static final của lớp trong Java
Thông thường, các hằng số liên quan đến lớp, được khai báo là static final để truy cập từ lớp mà không cần phải khởi tạo đối tượng.
public class MyClass {
public static final double PI;
static {
PI = 3.14159;
}
public static void main(String args[]) {
double banKinh = 20.0;
System.out.print("Dien tich hinh tron: ");
System.out.println(banKinh*banKinh*MyClass.PI);
}
}
Kết quả
Dien tich hinh tron: 1256.636