Bạn đang bước chân vào thế giới lập trình Java, đặc biệt là Lập trình hướng đối tượng. Vậy thì “Constructor” chắc chắn là một khái niệm bạn cần làm quen ngay từ đầu. Nắm vững Constructor (Hàm khởi tạo) trong Java là chìa khóa để tạo và quản lý đối tượng hiệu quả. Bài viết này từ InterData sẽ cung cấp cho bạn cái nhìn toàn diện nhất về hàm khởi tạo – Constructor là gì trong Java, các loại và đặc điểm của hàm khởi tạo,… Hãy cùng khám phá nhé!
Constructor là gì?
Constructor trong Java là một phương thức đặc biệt được sử dụng để khởi tạo đối tượng của một lớp. Khi bạn tạo một đối tượng mới bằng từ khóa new, constructor sẽ được gọi tự động để thiết lập các giá trị ban đầu cho các thuộc tính của đối tượng đó.
Constructor có tên trùng với tên lớp và không có kiểu trả về, khác với các phương thức thông thường. Nó giúp đảm bảo rằng mỗi đối tượng khi được tạo ra đều ở trạng thái hợp lệ với các giá trị mặc định hoặc giá trị do lập trình viên cung cấp.

Vai trò của Constructor trong lập trình hướng đối tượng
Vai trò của Constructor trong lập trình hướng đối tượng là:
- Khởi tạo đối tượng: Constructor đảm bảo rằng mỗi đối tượng khi được tạo ra đều có trạng thái hợp lệ và sẵn sàng sử dụng ngay từ đầu bằng cách thiết lập các giá trị ban đầu cho các thuộc tính của đối tượng.
- Tăng tính linh hoạt: Constructor có thể nhận tham số (parameterized constructor), giúp khởi tạo đối tượng với các giá trị khác nhau tùy theo ngữ cảnh sử dụng, từ đó tăng tính linh hoạt cho lớp.
- Duy trì tính nhất quán: Constructor giúp đảm bảo tính nhất quán của đối tượng bằng cách thiết lập các giá trị mặc định hoặc giá trị tùy chỉnh khi khởi tạo, giữ cho đối tượng luôn ở trạng thái ổn định và hợp lệ.
- Hỗ trợ tính đóng gói: Việc sử dụng constructor giúp tập trung logic khởi tạo vào một phương thức duy nhất, từ đó duy trì tính ổn định và dễ bảo trì cho mã nguồn.
- Tự động gọi khi tạo đối tượng: Constructor được gọi tự động khi đối tượng được tạo bằng từ khóa
new
, giúp lập trình viên không phải gọi thủ công các phương thức khởi tạo, giảm thiểu lỗi và tăng hiệu quả lập trình.
Constructor là thành phần cốt lõi trong lập trình hướng đối tượng, đảm bảo mọi đối tượng được tạo ra có trạng thái ban đầu hợp lệ, đồng thời hỗ trợ tính linh hoạt, nhất quán và đóng gói trong thiết kế phần mềm.
Các loại Constructor phổ biến trong Java
Trong ngôn ngữ lập trình Java, có ba loại constructor chính bạn cần nắm vững: Constructor mặc định, Constructor không tham số, và Constructor có tham số. Mỗi loại phục vụ mục đích khác nhau trong việc tạo và khởi tạo đối tượng.
Việc Java cung cấp các loại constructor khác nhau mang lại sự linh hoạt cho lập trình viên. Bạn có thể chọn hoặc định nghĩa constructor phù hợp nhất với cách bạn muốn các đối tượng của lớp mình được tạo ra và thiết lập trạng thái ban đầu.
Chúng ta sẽ lần lượt khám phá chi tiết từng loại constructor này. Từ constructor mặc định tự động được cung cấp, constructor không tham số do bạn tự định nghĩa, đến constructor có tham số để truyền dữ liệu khi tạo đối tượng.
Constructor mặc định (Default Constructor)
Constructor mặc định là constructor đặc biệt được trình biên dịch Java tự động thêm vào lớp của bạn. Điều này chỉ xảy ra khi bạn chưa hề khai báo bất kỳ constructor nào khác cho lớp đó. Nó có thân rỗng và không nhận bất kỳ tham số nào.
Mặc dù thân rỗng, constructor mặc định vẫn thực hiện một tác vụ ngầm định: gọi constructor không tham số của lớp cha. Nó cũng gán các giá trị mặc định cho các biến instance: số nguyên là 0, số thực là 0.0, boolean là false, và các tham chiếu đối tượng là null.
Cú pháp:
public ClassName() { // Các câu lệnh khởi tạo }
Ví dụ:
Java
public class MyClass {
// Không định nghĩa constructor nào
private int value;
private String text;
}
// Trong code sử dụng:
MyClass obj = new MyClass(); // Trình biên dịch gọi default constructor
// obj.value sẽ là 0, obj.text sẽ là null
Constructor không tham số (No-argument Constructor)
Đây là loại constructor do chính bạn, lập trình viên, tự tay viết. Giống như constructor mặc định, nó cũng không nhận bất kỳ đối số nào. Tuy nhiên, điểm khác biệt là bạn có toàn quyền tùy chỉnh logic khởi tạo bên trong thân của nó.
Bạn sẽ cần tự định nghĩa constructor không tham số tường minh nếu bạn đã viết các constructor có tham số khác nhưng vẫn muốn cung cấp một cách để tạo đối tượng mà không cần cung cấp bất kỳ giá trị đầu vào nào khi khởi tạo.
Cú pháp:
public ClassName() { // Các câu lệnh khởi tạo }
Ví dụ:
public class Person { private String name; private int age; // No-args constructor public Person() { name = “Unknown”; age = 0; }
Constructor có tham số (Parameterized Constructor)
Constructor có tham số là loại constructor mà bạn định nghĩa với một hoặc nhiều đối số (tham số) bên trong cặp dấu ngoặc đơn. Các tham số này cho phép bạn truyền dữ liệu từ bên ngoài vào để sử dụng trong quá trình khởi tạo đối tượng.
Mục đích chính là khởi tạo các biến instance của đối tượng với các giá trị cụ thể do người dùng cung cấp ngay tại thời điểm tạo đối tượng. Bạn có thể có nhiều constructor có tham số khác nhau (nạp chồng) tùy thuộc vào nhu cầu khởi tạo.
Cú pháp:
public ClassName(Type1 param1, Type2 param2, …) { // Các câu lệnh khởi tạo }
Ví dụ:
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; }
Đặc điểm nổi bật của Constructor
Constructor trong Java có những đặc điểm riêng biệt giúp nó thực hiện chức năng khởi tạo đối tượng. Các đặc điểm chính bao gồm tên trùng lớp, không có kiểu trả về, được gọi tự động, có phạm vi truy cập, không tĩnh, và có thể nạp chồng.
Hiểu rõ các đặc điểm của Constructor trong lập trình là cực kỳ quan trọng để sử dụng constructor đúng cách trong các ứng dụng Java. Nắm vững chúng giúp bạn tránh các lỗi phổ biến và viết code hiệu quả hơn khi làm việc với đối tượng.
Tên Constructor phải giống tên lớp
Quy tắc bắt buộc đầu tiên là tên của constructor phải hoàn toàn giống tên lớp mà nó thuộc về, bao gồm cả chữ hoa chữ thường. Đây là cách Java nhận biết một khối mã là constructor chứ không phải phương thức thông thường.
Việc tên trùng với tên lớp giúp máy ảo Java (JVM – Java Virtual Machine) biết chính xác constructor nào cần gọi khi bạn sử dụng từ khóa new
để tạo ra một đối tượng mới từ lớp đó. Nó là định danh duy nhất cho vai trò khởi tạo này.

Constructor không có kiểu trả về
Constructor trong Java tuyệt đối không có bất kỳ kiểu dữ liệu trả về nào. Ngay cả từ khóa void
cũng không được sử dụng trước tên constructor. Đây là một trong những điểm khác biệt cơ bản nhất so với phương thức (method).
Việc không có kiểu trả về nhấn mạnh rằng mục đích của constructor không phải là thực hiện một phép tính hay trả về một giá trị. Chức năng duy nhất của nó là thiết lập trạng thái ban đầu của đối tượng vừa được tạo ra trong bộ nhớ.
Constructor được gọi tự động khi tạo đối tượng
Constructor được gọi một cách tự động bởi JVM ngay sau khi bộ nhớ được cấp phát cho đối tượng mới được tạo. Điều này xảy ra khi bạn sử dụng toán tử new
kèm theo tên constructor tương ứng, ví dụ: new TenLop()
.
Mỗi đối tượng chỉ được gọi constructor một lần duy nhất trong suốt vòng đời của nó, chính là thời điểm đối tượng đó được tạo ra. Bạn không thể gọi constructor một cách thủ công sau khi đối tượng đã được tạo xong.
Constructor có thể có phạm vi truy cập (Access Modifiers)
Constructor có thể sử dụng các phạm vi truy cập (access modifiers) như public
, private
, protected
, hoặc để mặc định. Điều này kiểm soát nơi mà các đối tượng của lớp có thể được phép tạo ra từ bên ngoài lớp đó.
Ví dụ, một constructor public
cho phép tạo đối tượng từ bất kỳ đâu. Một constructor private
chỉ cho phép tạo đối tượng ngay bên trong lớp đó, thường dùng trong các mẫu thiết kế như Singleton.
Constructor không thể ghi đè (Override) nhưng có thể nạp chồng (Overload)
Constructor không được kế thừa bởi lớp con như các phương thức thông thường, do đó bạn không thể sử dụng cơ chế ghi đè (override) đối với constructor. Mỗi lớp có constructor riêng của nó.
Tuy nhiên, một lớp hoàn toàn có thể có nhiều constructor khác nhau. Điều này được gọi là nạp chồng constructor (constructor overloading), cho phép bạn định nghĩa nhiều cách khác nhau để tạo và khởi tạo đối tượng dựa trên các tập hợp tham số khác nhau.
Sự khác biệt giữa Method và Constructor trong Java
Mặc dù cả method và constructor đều là các khối mã trong Java, chúng có nhiều khác biệt cơ bản. Sự khác nhau nằm ở mục đích, cách đặt tên, kiểu trả về, cách gọi, khả năng kế thừa và sử dụng từ khóa static
.
Việc phân biệt rõ ràng giữa method và Constructor trong lập trình là rất quan trọng đối với người học Java. Hiểu đúng chức năng và quy tắc của từng loại giúp bạn sử dụng chúng hiệu quả, tránh nhầm lẫn và viết code chuẩn xác theo nguyên tắc OOP.
Dưới đây, bài viết sẽ giải thích sự khác nhau giữa constructor và method:
Mục đích sử dụng
Constructor được thiết kế với mục đích duy nhất là khởi tạo trạng thái ban đầu cho đối tượng. Nó chạy ngay khi đối tượng được tạo ra để gán giá trị cho các biến instance, đảm bảo đối tượng ở trạng thái sẵn sàng hoạt động.
Ngược lại, method (phương thức) được dùng để thực hiện một hành động hoặc một tập hợp các lệnh logic cụ thể. Method biểu diễn các hành vi mà đối tượng có thể thực hiện trong suốt vòng đời của nó.

Quy tắc đặt tên
Quy tắc đặt tên constructor rất nghiêm ngặt: tên của nó bắt buộc phải giống hệt tên của lớp chứa nó, kể cả việc phân biệt chữ hoa chữ thường. Đây là cách JVM nhận diện constructor.
Với method, bạn có thể đặt bất kỳ tên nào tuân thủ quy tắc đặt tên biến/phương thức hợp lệ trong Java (bắt đầu bằng chữ cái, _, $, không chứa ký tự đặc biệt…). Tên method thường biểu thị hành động của nó.
Kiểu trả về
Điểm khác biệt lớn là constructor không có bất kỳ kiểu dữ liệu trả về nào. Ngay cả từ khóa void
cũng không được sử dụng. Constructor chỉ đơn thuần là xây dựng và trả về chính đối tượng mới được tạo.
Trong khi đó, method luôn có một kiểu dữ liệu trả về. Kiểu trả về này có thể là một kiểu dữ liệu nguyên thủy, một đối tượng, hoặc void
nếu phương thức đó không trả về giá trị nào.
Cách gọi (Invocation)
Constructor được gọi tự động bởi hệ thống khi bạn sử dụng từ khóa new
để tạo một đối tượng mới. Bạn không gọi nó bằng tên đối tượng chấm (.).
Method cần được gọi một cách tường minh bởi lập trình viên sử dụng tham chiếu đến đối tượng, theo cú pháp objectName.methodName()
. Method có thể được gọi nhiều lần trong suốt vòng đời đối tượng.
Kế thừa và Ghi đè
Constructor không được kế thừa từ lớp cha sang lớp con. Mỗi lớp có constructor riêng của nó. Vì không kế thừa nên constructor cũng KHÔNG THỂ bị ghi đè (override) trong lớp con.
Ngược lại, method có thể được kế thừa từ lớp cha sang lớp con (trừ các method private
hoặc static
). Lớp con cũng CÓ THỂ ghi đè (override) các method của lớp cha để thay đổi hành vi.
Từ khóa Static
Constructor không thể được khai báo với từ khóa static
. Lý do là constructor làm việc trên các biến instance của từng đối tượng, trong khi thành viên static thuộc về lớp chứ không phải đối tượng cụ thể.
Method có thể được khai báo là static
. Static method thuộc về lớp và có thể được gọi trực tiếp từ tên lớp mà không cần tạo đối tượng. Static method chỉ có thể truy cập thành viên static khác.
Bảng so sánh giữa Method và Constructor:
Đặc điểm | Constructor | Method |
---|---|---|
Tên | Phải giống tên lớp. | Có thể là bất kỳ tên hợp lệ nào. |
Kiểu trả về | Không có bất kỳ kiểu trả về nào. | Phải có kiểu trả về (bao gồm void). |
Mục đích | Khởi tạo trạng thái đối tượng. | Thực hiện một hành động/chức năng cụ thể. |
Cách gọi | Tự động gọi khi tạo đối tượng (new). | Cần gọi tường minh bằng tên đối tượng (object.method()). |
Từ khóa new |
Được gọi sau từ khóa new. | Không liên quan trực tiếp đến new. |
Ghi đè | Không thể ghi đè (Override). | Có thể ghi đè (Override). |
Nạp chồng | Có thể nạp chồng (Overload). | Có thể nạp chồng (Overload). |
Lỗi thường gặp khi sử dụng Constructor trong Java
Dưới đây là một số lỗi phổ biến bạn cần tránh khi làm việc với constructor trong Java:
Viết logic phức tạp trong Constructor
Constructor nên giữ đơn giản, chỉ tập trung vào việc khởi tạo các thuộc tính của đối tượng. Việc viết các đoạn mã logic phức tạp hoặc các thao tác tốn thời gian trong constructor có thể làm chậm quá trình tạo đối tượng và ảnh hưởng hiệu suất ứng dụng1.
Không kiểm tra giá trị null cho tham số đầu vào
Khi constructor nhận tham số, nếu không kiểm tra giá trị null trước khi gán hoặc xử lý, rất dễ gây ra lỗi NullPointerException trong quá trình khởi tạo đối tượng. Vì vậy, cần luôn xác thực các tham số đầu vào để tránh lỗi này.
Định nghĩa Constructor có kiểu trả về (void hoặc kiểu khác)
Một lỗi phổ biến là viết constructor giống như một phương thức thông thường với kiểu trả về (ví dụ void). Điều này khiến phương thức đó không phải là constructor mà chỉ là một phương thức bình thường, làm mất đi chức năng khởi tạo đối tượng và gây nhầm lẫn.
Không khai báo Constructor mặc định khi đã định nghĩa Constructor có tham số
Khi bạn định nghĩa một constructor có tham số, Java sẽ không tự động tạo constructor mặc định (không tham số). Nếu bạn cố gắng tạo đối tượng bằng constructor mặc định mà không khai báo nó, chương trình sẽ báo lỗi biên dịch.
Gọi constructor khác trong cùng lớp không đúng cách
Khi sử dụng this() để gọi một constructor khác trong cùng lớp (constructor overloading), câu lệnh gọi này phải nằm ở dòng đầu tiên của constructor. Nếu không, mã nguồn sẽ không biên dịch được.
Hiểu và tránh các lỗi phổ biến khi sử dụng constructor sẽ giúp bạn phát triển phần mềm nhanh hơn, tránh lỗi biên dịch và lỗi runtime không mong muốn. Luôn giữ constructor đơn giản, kiểm tra tham số đầu vào và tuân thủ đúng cú pháp sẽ giúp bạn tận dụng tối đa lợi ích của hàm khởi tạo trong Java.
Nguyên tắc để viết constructor đơn giản, hiệu quả và tránh lỗi
Dưới đây là các nguyên tắc để viết constructor đơn giản, hiệu quả và tránh lỗi trong Java:
- Đặt tên Constructor trùng với tên lớp: Constructor phải có tên giống hệt tên lớp, phân biệt chữ hoa chữ thường. Đây là quy tắc bắt buộc để Java nhận diện đúng constructor.
- Không khai báo kiểu trả về cho Constructor: Constructor không có kiểu trả về, không được khai báo
void
hay bất kỳ kiểu dữ liệu nào khác. Điều này giúp phân biệt constructor với các phương thức thông thường. - Giữ Constructor đơn giản, chỉ dùng để khởi tạo: Tránh viết các đoạn logic phức tạp hoặc xử lý nặng trong constructor. Constructor nên tập trung vào việc gán giá trị ban đầu cho các thuộc tính của đối tượng, giúp quá trình tạo đối tượng nhanh và hiệu quả hơn.
- Sử dụng Constructor không tham số và có tham số hợp lý: Định nghĩa Constructor không tham số (no-arg constructor) để hỗ trợ tạo đối tượng mặc định khi cần và định nghĩa Constructor có tham số (parameterized constructor) để khởi tạo đối tượng với giá trị cụ thể, tăng tính linh hoạt.
- Kiểm tra và xác thực tham số đầu vào: Khi Constructor nhận tham số, nên kiểm tra giá trị null hoặc giá trị không hợp lệ để tránh lỗi runtime như
NullPointerException
trong quá trình khởi tạo. - Tránh gọi Constructor phức tạp hoặc gọi các phương thức khác trong Constructor: Việc gọi các phương thức phức tạp hoặc thao tác I/O trong constructor có thể gây ra lỗi hoặc làm chậm quá trình tạo đối tượng.
- Sử dụng
this()
để tái sử dụng Constructor trong cùng lớp: Khi có nhiều constructor, nên dùngthis()
để gọi lại constructor khác nhằm tránh trùng lặp mã và giữ mã nguồn gọn gàng. - Gọi
super()
trong lớp con khi lớp cha không có constructor mặc định: Nếu lớp cha không có constructor không tham số, lớp con phải gọisuper()
với tham số phù hợp để tránh lỗi biên dịch. - Sử dụng phạm vi truy cập (access modifiers) phù hợp: Chọn phạm vi truy cập cho constructor (
public
,private
,protected
) tùy theo mục đích sử dụng, ví dụ constructorprivate
dùng trong mẫu Singleton để hạn chế tạo đối tượng bên ngoài. - Không tạo constructor quá nhiều hoặc quá phức tạp: Quá nhiều constructor hoặc constructor quá phức tạp làm khó bảo trì và dễ gây nhầm lẫn, nên giữ số lượng constructor vừa phải và rõ ràng.
Tuân thủ những nguyên tắc trên giúp bạn viết constructor trong Java vừa đơn giản, dễ hiểu, vừa tránh được các lỗi phổ biến, đồng thời nâng cao hiệu quả và chất lượng mã nguồn trong dự án phát triển phần mềm.