NỘI DUNG BÀI VIẾT
Như đã biết, trong Java để khởi tạo một instance của một class chúng ta sẽ sử dụng từ khóa new. Tuy nhiên, trong một số trường hợp chúng ta cần tạo một instance khi chỉ biết tên class hoặc private constructor hoặc không biết được số lượng tham số của constructor, … Với những trường hợp như vậy, chúng ta không thể gọi từ khóa new một cách trực tiếp mà sẽ sử dụng một số cách đặc biệt và chúng ta sẽ cùng tìm hiểu các cách giải quyết vấn đề này trong phần tiếp theo của bài viết.
Sử dụng Reflection khi biết tên class
Một trong những cách đơn giản và thường được sử dụng để tạo instance của một class là sử dụng kỹ thuật Reflection. Nếu bạn chưa biết về Reflection, hãy dành chút thời gian xem lại bài viết Hướng dẫn sử dụng Java Reflection.
Sử dụng newInstance() khi class có constructor không có tham số và phạm vi truy cập không phải private
package com.gpcoder.instance; public class Employee { private int id; private String name; public Employee() { super(); } public Employee(int id, String name) { super(); this.id = id; this.name = name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } }
Tạo instance sử dụng newInstance():
package com.gpcoder.instance; import java.lang.reflect.InvocationTargetException; public class NewInstanceExample { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // Get class based on the given class name Class<?> clazz = Class.forName("com.gpcoder.instance.Employee"); // Create a new instance with empty argument of constructor of a class Employee employee = (Employee) clazz.newInstance(); employee.setId(1); employee.setName("gpcoder"); System.out.println("employee: " + employee); } }
Lưu ý:
- Nếu không tồn tại constructor không có tham số, chương trình sẽ throw ra một exception như sau:
Exception in thread "main" java.lang.InstantiationException: com.gpcoder.instance.Employee at java.lang.Class.newInstance(Class.java:427) at com.gpcoder.instance.NewInstanceExample.main(NewInstanceExample.java:15) Caused by: java.lang.NoSuchMethodException: com.gpcoder.instance.Employee.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.newInstance(Class.java:412) ... 1 more
Sử dụng getConstructor() khi constructor của class là public
Chúng ta sẽ tạo instance của class Employee sử dụng phương thức getConstructor():
package com.gpcoder.instance; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ConstructorNewInstanceExample { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // Get class based on the given class name Class<?> clazz = Class.forName("com.gpcoder.instance.Employee"); // Get all constructor of the class Constructor<?>[] allConstructors = clazz.getConstructors(); for (Constructor<?> constructor : allConstructors) { Class<?>[] parameters = constructor.getParameterTypes(); if (parameters.length == 0) { // Create a new instance without parameter Employee employee1 = (Employee) constructor.newInstance(); employee1.setId(1); employee1.setName("gpcoder 1"); System.out.println("employee1: " + employee1); } else if (parameters.length == 2) { // Create a new instance with two parameters Employee employee2 = (Employee) constructor.newInstance(2, "gpcoder 2"); System.out.println("employee2: " + employee2); } } // Create a new instance with specific constructor of class Constructor<?> constructor = clazz.getConstructor(int.class, String.class); Employee employee3 = (Employee) constructor.newInstance(3, "gpcoder 3"); System.out.println("employee3: " + employee3); } }
Output của chương trình:
Sử dụng getDeclaredConstructor() khi constructor của class là private
package com.gpcoder.instance; public class PrivateEmployee { private int id; private String name; private PrivateEmployee(int id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return "PrivateEmployee [id=" + id + ", name=" + name + "]"; } }
Sử dụng getDeclaredConstructor() khi các constructor của class là private:
package com.gpcoder.instance; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class PrivateConstructorNewInstanceExample { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // Get class based on the given class name Class<?> clazz = Class.forName("com.gpcoder.instance.PrivateEmployee"); // Get the private constructor. Constructor<?> constructor = clazz.getDeclaredConstructor(int.class, String.class); // Since it is private, make it accessible. constructor.setAccessible(true); // Create a new instance with specific constructor of class PrivateEmployee employee = (PrivateEmployee) constructor.newInstance(1, "gpcoder"); System.out.println("employee: " + employee); } }
Output của chương trình:
employee: PrivateEmployee [id=1, name=gpcoder]
Tìm hiểu khoá học lập trình Web trong vòng 5 tháng!
Nguồn: https://gpcoder.com/5525-lam-the-nao-tao-instance-cua-mot-class-ma-khong-goi-tu-khoa-new/