Trong lập trình Java, từ khóa static
được sử dụng rất nhiều. Từ khóa static
trong Java dùng để tạo một biến cấp lớp (class level variable). Các biến và phương thức static
là một phần của lớp class, không phải của các thể hiện (instances) của class đó.
Từ khóa static trong Java
Từ khóa static
trong Java có thể được sử dụng trong năm trường hợp, nó được minh họa trong hình ảnh dưới đây.
Chúng ta sẽ thảo luận về bốn trường hợp trong số đó ở đây. Trường hợp thứ năm được giới thiệu trong Java 8 và đã được thảo luận trong bài viết: **Các tính năng nổi bật của Java 8.**
1. Java static variable
Bạn có thể dùng từ khóa static
với một biến cấp lớp. Một biến static
là biến của lớp và không thuộc về object/instance của lớp. Vì các biến static
được chia sẻ giữa tất cả các instance của object, chúng không an toàn trong môi trường đa luồng. Thông thường, các biến static
được sử dụng cùng với từ khóa final
cho các tài nguyên hoặc hằng số chung mà tất cả các đối tượng có thể dùng. Nếu biến static
không phải là private, bạn có thể truy cập nó bằng cú pháp ClassName.variableName
.
//static variable example
private static int count;
public static String str;
public static final String DB_USER = "myuser";
2. Java static method
Tương tự biến static, phương thức static thuộc về lớp chứ không phải các instance của lớp. Một phương thức static chỉ có thể truy cập các biến static của class và chỉ gọi các phương thức static của lớp. Thông thường, các phương thức static là các phương thức tiện ích (utility methods) mà chúng ta muốn công khai để các lớp khác sử dụng mà không cần tạo một instance. Ví dụ, lớp Collections. Các lớp Wrapper và các lớp tiện ích chứa rất nhiều phương thức static. Phương thức main()
là điểm khởi đầu của một chương trình Java, bản thân nó cũng là một phương thức static.
//static method example
public static void setCount(int count) {
if(count > 0)
StaticExample.count = count;
}
//static util method
public static int addInts(int i, int...js){
int sum=i;
for(int x : js) sum+=x;
return sum;
}
Kể từ Java 8 trở đi, chúng ta có thể có các phương static
trong interface
3. Java static block
Java static block là một nhóm các câu lệnh được thực thi khi lớp được nạp vào bộ nhớ bởi Java ClassLoader. Static block được dùng để khởi tạo các biến static của lớp. Phần lớn, nó được sử dụng để tạo các tài nguyên static khi lớp được nạp. Chúng ta không thể truy cập các biến non-static trong static block. Chúng ta có thể có nhiều static block trong một class, mặc dù điều này không thực sự hợp lý. Mã trong static block chỉ được thực thi một lần duy nhất khi lớp được nạp vào bộ nhớ.
static{
//can be used to initialize resources when class is loaded
System.out.println("StaticExample static block");
//can access only static variables and methods
str="Test";
setCount(2);
}
4. Java Static Class
Chúng ta có thể sử dụng từ khóa static với các nested class (lớp lồng). Tuy nhiên, từ khóa static không thể được sử dụng với các top-level class (lớp cấp cao nhất). Một static nested class tương tự như bất kỳ top-level class nào khác và việc lồng chỉ nhằm mục đích tổ chức mã nguồn cho thuận tiện..
Hãy cùng xem tất cả các trường hợp sử dụng từ khóa static trong Java trong một chương trình mẫu: StaticExample.java
.
package com.journaldev.misc;
public class StaticExample {
//static block
static{
//can be used to initialize resources when class is loaded
System.out.println("StaticExample static block");
//can access only static variables and methods
str="Test";
setCount(2);
}
//multiple static blocks in same class
static{
System.out.println("StaticExample static block2");
}
//static variable example
private static int count; //kept private to control its value through setter
public static String str;
public int getCount() {
return count;
}
//static method example
public static void setCount(int count) {
if(count > 0)
StaticExample.count = count;
}
//static util method
public static int addInts(int i, int...js){
int sum=i;
for(int x : js) sum+=x;
return sum;
}
//static class example - used for packaging convenience only
public static class MyStaticClass{
public int count;
}
}
Hãy cùng xem cách sử dụng biến static, phương thức static và lớp static trong một chương trình thử nghiệm: TestStatic.java
.
package com.journaldev.misc;
public class TestStatic {
public static void main(String[] args) {
StaticExample.setCount(5);
//non-private static variables can be accessed with class name
StaticExample.str = "abc";
StaticExample se = new StaticExample();
System.out.println(se.getCount());
//class and instance static variables are same
System.out.println(StaticExample.str +" is same as "+se.str);
System.out.println(StaticExample.str == se.str);
//static nested classes are like normal top-level classes
StaticExample.MyStaticClass myStaticClass = new StaticExample.MyStaticClass();
myStaticClass.count=10;
StaticExample.MyStaticClass myStaticClass1 = new StaticExample.MyStaticClass();
myStaticClass1.count=20;
System.out.println(myStaticClass.count);
System.out.println(myStaticClass1.count);
}
}
Kết quả của chương trình ví dụ về từ khóa static trong Java ở trên là:
StaticExample static block
StaticExample static block2
5
abc is same as abc
true
10
20
Lưu ý rằng mã trong static block được thực thi đầu tiên và chỉ một lần duy nhất ngay sau khi class được nạp vào bộ nhớ. Các output khác tự giải thích.
Java static import
Thông thường chúng ta truy cập các thành viên static bằng cách sử dụng Class reference. Từ Java 1.5, chúng ta có thể sử dụng java static import để tránh việc phải dùng class reference. Dưới đây là một ví dụ đơn giản về Java static import.
package com.journaldev.test;
public class A {
public static int MAX = 1000;
public static void foo(){
System.out.println("foo static method");
}
}
package com.journaldev.test;
import static com.journaldev.test.A.MAX;
import static com.journaldev.test.A.foo;
public class B {
public static void main(String args[]){
System.out.println(MAX); //normally A.MAX
foo(); // normally A.foo()
}
}
Lưu ý các câu lệnh import
, đối với static import chúng ta phải sử dụng import static theo sau là tên đầy đủ của thành phần static trong lớp. Để import tất cả các static member của một lớp, chúng ta có thể sử dụng * như trong import static com.journaldev.test.A.*;. Chúng ta chỉ nên sử dụng nó khi chúng ta sử dụng static variable của một class nhiều lần, vì nếu lạm dụng sẽ làm giảm tính dễ đọc của mã nguồn.