Mục lục
Từ khóa this trong Java được sử dụng để tham chiếu đến instance hiện tại được tạo ra từ class.
Trong Java từ khóa this có thể được dùng trong các trường hợp sau:
- Tham chiếu biến instance của class
- Tham chiếu đến các method của class
- this() để gọi constructor
- this có thể sử dụng như một tham số của method
- this có thể sử dụng như một tham số của constructor
- Dùng this để trả về object class instance
This tham chiếu đến biến instance
Từ khóa this có thể dùng để tham chiếu đến các biến instance của class hiện tại. Nó rất hữu dụng để phân biệt giữa biến instance của class với các param của method hoặc constructor khi chúng có cùng tên.
Problem
Student class chứa parameterized constructor nhận một thông số đầu vào là String name.
// File Student.java public class Student { String name; Student(String name) { name = name; } void display() { System.out.println(name); } }
Tiếp theo, tạo Student với name là shareprogramming.net. Và mong đợi của mình là khi gọi method display() sẽ trả về kết quả shareprogramming.net.
// File Main.java public class Main { public static void main(String [] args) { Student student = new Student("shareprogramming.net"); student.display(); } }
Output: null
Thế nhưng mà thực tế mình nhận được là null. À ha, code vẫn không báo lỗi lầm gì nhé các bạn. Kết quả như trên thì khó hiểu quá ta.
Chúng ta xem lại một xíu ở trên thì thấy tên của tham số trùng với tên thuộc tính name trong Student class. Vậy nên trình biên dịch sẽ hiểu nhầm và nó sẽ gán giá trị từ biến name truyền vào cho chính nó.
Cách giải quyết
Ở vấn đề trên trên để giải quyết chúng ta có 2 cách:
- Đổi tên tham số
- Sử dụng từ khóa this
Với việc đổi tên tham số sao cho khác biến instance của class là hoàn toàn hợp lệ. Thế nhưng về mặt ngữ nghĩa khi bạn đổi tên các tham số như vậy sẽ khiến code trở nên khó hiểu và dễ bi phạm quy tắc đặt tên biến trong java.
Sử dụng từ khóa this là một option khá sịn với việc nó có thể giữ nguyên ngữ nghĩa của tham số truyền vào, và tránh sự hiểu nhầm cho trình biên dịch.
Mình sẽ đổi một xíu code bên trong Student class. Nó sẽ thành như này
// File Student.java public class Student { String name; Student(String name) { this.name = name; } void display() { System.out.println(name); } }
Chạy hàm main và output là: shareprogramming.net
This tham chiếu đến method
Mình sẽ lấy ví dụ sau, các bạn xem code trước nha
// File Example.java class Example { Example() { System.out.println("Constructor duoc goi"); // call method by this this.hello(); } void hello() { System.out.println("Hello anh em"); } }
// File Main.java public class Main { public static void main(String [] args) { Example example = new Example(); } }
Output:
Constructor duoc goi
Hello anh em
Các bạn thấy trong constructor ngoài việc mình xuất ra màn hình câu Constructor duoc goi thì mình cũng đã dùng this để call tới method hello().
Như một trong một class chúng ta hoàn toàn có thể dùng từ khóa this để call các method của chính nó nhé.
This để gọi đến constructor
Sử dụng this() để gọi đến constructor của class. Lưu ý
- this() phải được đặt ở đầu tiên trong constructor
- Phải có 2 constructor trở lên, và chúng gọi lẫn nhau thông qua this().
Ví dụ 1 constructor không có tham số gọi constructor có tham số
// File Example.java class Example { Example() { this("shareprogramming.net"); System.out.println("Constructor duoc goi"); } Example(String name) { System.out.println(name); } }
// File Main.java public class Main { public static void main(String [] args) { Example example = new Example(); } }
Output:
shareprogramming.net
Constructor duoc goi
Ví dụ 2 constructor có tham số gọi constructor không có tham số
// File Example.java class Example { Example() { System.out.println("Constructor duoc goi"); } Example(String name) { this(); System.out.println(name); } }
// File Main.java public class Main { public static void main(String[] args) { Example example = new Example("shareprogramming.net"); } }
Output:
Constructor duoc goi
shareprogramming.net
This như tham số đầu vào của method
// File Example.java class Example { Example() {} void m(Example example) { System.out.println(example.getClass().getName()); } void p() { m(this); } }
// File Main.java public class Main { public static void main(String[] args) { Example example = new Example(); example.p(); } }
Output: com.company.Example
Chúng ta có method p() gọi đến method m(), trong đó m cần một tham số là một object type Example. Vì object hiện tại cũng là một object kiểu Example nên chúng ta hoàn toàn có thể truyền this cho m().
This như tham số đầu vào của constructor
// File ExampleA.java class ExampleA { ExampleA(ExampleB exampleB) { System.out.println("Constructor: " + this.getClass().getName()); System.out.println("Constructor: " + exampleB.getClass().getName()); } } // File ExampleB.java public class ExampleB { ExampleB(){} void m() { ExampleA exampleA = new ExampleA(this); } }
// File Main.java public class Main { public static void main(String[] args) { ExampleB exampleB = new ExampleB(); exampleB.m(); } }
Constructor ExampleA cần tham số ExampleB, thế nên khi ta khởi tạo Object ExampleA trong ExampleB thì ta hoàn toàn có thể truyền this.
This để trả về object class instance
Khi chúng ta cần lấy một object instance class, sử dụng return this để trả về.
// File ExampleA.java ExampleA class Example { Example() {} Example getInstance() { return this; } }
//File ExampleA.java public class Main { public static void main(String[] args) { Example example = new Example(); System.out.println(example.getInstance().getClass().getName()); } }
Output: com.company.Example
Tóm lược
Chúng ta vừa đi qua những cách sử dụng từ khóa this trong java. Có rất nhiều cách để sử dụng this. Thế nhưng với kinh nghiệm của mình mình sẽ thấy các trường hợp sử dụng phổ biến:
- Lấy object class instance
- Dùng this cho tham số
Còn cách trường hợp khác hầu như ít gặp và mình cũng chưa từng thấy qua ai sử dụng vậy luôn =). Nếu ai mà nhớ hết thì tốt, không thì nhớ 2 cách mình nêu trên là ok rồi đó.
Nguồn tham khảo