Phản chiếu trong Java rất dễ dàng
Javaのsự phản xạPhần này giới thiệu các lớp tiện ích giúp việc sử dụng API trở nên dễ dàng hơn.
Phản chiếu là gì?
API phản chiếurăng,"java.lang.reflectNó đã được bao gồm trong gói sản phẩm.
API này truy xuất thông tin như các trường và phương thức từ các lớp Java.
Chúng ta chủ yếu sẽ sử dụng các lớp sau.
- java.lang.Class
- java.lang.reflect.Constructor
- java.lang.reflect.Method
- java.lang.reflect.field
sự phản xạSử dụng phương pháp này, bạn có thể tránh việc trực tiếp lập trình việc tạo lớp và gọi phương thức.
Bạn có thể tạo các thể hiện của lớp và thực thi các phương thức từ chuỗi ký tự.
Bằng cách định nghĩa tên lớp và tên phương thức trong các tệp bên ngoài như XML, các ứng dụng có thể được điều chỉnh linh hoạt để thích ứng với những thay đổi trong môi trường thời gian chạy.
Hơn nữa, đây là một API rất hiệu quả để xây dựng các ứng dụng có tính linh hoạt cao.
Mục đích của sự suy ngẫm
sự phản xạMặc dù người dùng không thường xuyên sử dụng trực tiếp chức năng này,
Nó được sử dụng rộng rãi trong các ứng dụng web như Struts và trong các framework như O/R mapping.
Ví dụ, khi bạn muốn tự động thiết lập dữ liệu đầu vào từ màn hình web vào các thuộc tính của JavaBeans,
Ví dụ, điều này được sử dụng khi thực hiện các truy vấn SQL để tự động cập nhật các thuộc tính của JavaBeans.
Hơn nữa, các tính năng như tải và đăng ký động các plugin giúp mở rộng chức năng của ứng dụng khi khởi động cũng có sẵn.sự phản xạĐiều này có thể dễ dàng đạt được bằng cách sử dụng [phương pháp này].
Thực thi ví dụ
Giờ thì hãy chạy đoạn mã mẫu và tự mình trải nghiệm lập trình dựa trên framework nhé.
Ở đây chúng ta sẽ sử dụng các lớp sausự phản xạĐây là một cách đơn giản để sử dụng tiện ích này.
Main.java...Lớp cần thực thi
BeanUtil.java...Lớp tiện ích phản chiếu
FreeSoft.java...Đây là một lớp đại diện cho phần mềm tự do và được sử dụng như một hình thức phản chiếu.
●Khi được thực hiện như thường lệ
FreeSoft freeSoft = new FreeSoft();
freeSoft.setName(Trò chuyện & Nhắn tin - Cả trò chuyện và nhắn tin nữa!!)“);
freeSoft.showName();
freeSoft.showPrice(0);
●Khi được thực thi bằng cách sử dụng phản chiếu
// Tạo một thể hiện của lớp FreeSoft
Object invokeObject = BeanUtil.newInstance("Phần mềm miễn phí")“);
// Đặt giá trị cho trường tên.
BeanUtil.setProperty(invokeObject, “"tên"” , “"Trò chuyện & Nhắn tin - Cả trò chuyện và nhắn tin nữa!!"”);
// Thực thi phương thức showName() của FreeSoft.
BeanUtil.invoke(invokeObject, “showName”, vô giá trị);
// Thực thi phương thức showPrice() của FreeSoft.
// Nếu phương thức có tham số, chúng phải được truyền dưới dạng một mảng kiểu Object.
BeanUtil.invoke(invokeObject, “showPrice”,new Object[]{new Integer(0)});
●Kết quả thực thi
Kết quả thực thi sẽ giống nhau cho dù bạn sử dụng reflection hay không.
Tên phần mềm: Chat&Messenger (Trò chuyện và nhắn tin)!
Giá: 0 yên
>>>Khi sử dụng phản chiếu
Tên phần mềm: Chat&Messenger (Trò chuyện và nhắn tin)!
Giá: 0 yên
Chi tiết phương thức BeanUtil
newInstance
public static Object newInstance(String className) ném ra ngoại lệ
- Thao tác này tạo và trả về một thể hiện từ chuỗi "className".
-
- Thông số:
tên lớp- Tên lớp học đủ điều kiện- Giá trị trả về:
- Một thể hiện mới của tên lớp đủ điều kiện.
- ngoại lệ:
Ngoại lệ
newInstance
public static Object newInstance(String className, Object[] argObj) throws Exception
- Thao tác này tạo và trả về một thể hiện từ chuỗi "className".
-
- Thông số:
tên lớp- Tên lớp học đủ điều kiệnargObj– Tham số khởi tạo- Giá trị trả về:
- Một thể hiện mới của tên lớp đủ điều kiện.
- ngoại lệ:
Ngoại lệ
newInstance
public static Object newInstance(Lớp clazz) ném ra ngoại lệ
- Thao tác này tạo và trả về một thể hiện từ lớp "clazz".
-
- Thông số:
Clazz- lớp học- Giá trị trả về:
- Một trường hợp mới của clazz
- ngoại lệ:
Ngoại lệ
newInstance
public static Object newInstance(Class clazz, Object[] argObj) throws Exception
- Thao tác này tạo và trả về một thể hiện từ lớp "clazz".
-
- Thông số:
Clazz- lớp họcargObj– Tham số khởi tạo- Giá trị trả về:
- Một trường hợp mới của clazz
- ngoại lệ:
Ngoại lệ
đặt thuộc tính
public static void đặt thuộc tính(Object invokeObject, String fieldName, Object value) throws Exception
- Phương thức setter của trường "fieldName" thuộc đối tượng "invokeObject" được gọi để lưu trữ giá trị "value".
Nếu không có phương thức setter, giá trị sẽ được gán trực tiếp cho trường. Tuy nhiên, trong trường hợp này, thuộc tính mục tiêu phải có thuộc tính public.
-
- Thông số:
InvokeObject- Đối tượng cần được thực thiTên trường– Tên thuộc tính của đối tượng cần được thực thiKhuyến khích– Giá trị cần thiết lập- ngoại lệ:
Ngoại lệ– Lỗi sau đây xảy ra:InvocationTargetException- Khi phương thức cơ bản ném ra một ngoại lệNgoại lệ truy cập bất hợp pháp– Đối tượng Phương thức này là Java
Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.NoSuchMethodException- Nếu không tìm thấy phương thức có tên được chỉ định
lấy thuộc tính
public static Object lấy thuộc tính(Object invokeObject, String fieldName) throws Exception
- Phương thức getter của trường fieldName thuộc đối tượng invokeObject được gọi để truy xuất giá trị của nó.
Nếu không có phương thức getter, giá trị sẽ được lấy trực tiếp từ trường. Tuy nhiên, trong trường hợp này, thuộc tính mục tiêu phải có thuộc tính là public. -
- Thông số:
InvokeObject- Đối tượng cần được thực thiTên trường– Tên thuộc tính của đối tượng cần được thực thi- Giá trị trả về:
- Giá trị trả về của phương thức getter
- ngoại lệ:
Ngoại lệ– Lỗi sau đây xảy ra:InvocationTargetException- Khi phương thức cơ bản ném ra một ngoại lệNgoại lệ truy cập bất hợp pháp– Đối tượng Phương thức này là Java
Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.NoSuchFieldException- Nếu không tìm thấy trường có tên được chỉ định
gọi
public static Object gọi(Object invokeObject, String callMethod, Object[] argObjects) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
- Thao tác này thực thi phương thức "callMethod" của đối tượng "invokeObject".
Nếu có giá trị trả về, giá trị đó có thể được nhận dưới dạng một đối tượng. -
- Thông số:
InvokeObject- Đối tượng cần được thực thigọi phương thức– Tên của phương thức cần thực thiargObjects– Nếu có tham số, hãy truyền chúng dưới dạng mảng các đối tượng. Nếu không có tham số, hãy truyền giá trị null.- Giá trị trả về:
- Giá trị trả về của việc thực thi "callMethod"
- ngoại lệ:
InvocationTargetException- Khi phương thức cơ bản ném ra một ngoại lệNgoại lệ truy cập bất hợp pháp– Đối tượng Phương thức này là Java
Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.NoSuchMethodException- Nếu không tìm thấy phương thức có tên được chỉ định
tìm phương thức
Phương thức tĩnh công khai tìm phương thức(Object invokeObject, String callMethod, Object[] argObjects) throws NoSuchMethodException
- Thao tác này tìm kiếm phương thức "callMethod" của đối tượng "invokeObject".
-
- Thông số:
InvokeObject- Đối tượng cần được thực thigọi phương thức– Tên phương thức của đối tượng cần được thực thiargObjects– Nếu có tham số, hãy truyền chúng dưới dạng mảng các đối tượng. Nếu không có tham số, hãy truyền giá trị null.- Giá trị trả về:
- Các đối tượng phương thức đáp ứng các điều kiện của các đối số được chỉ định.
- ngoại lệ:
NoSuchMethodException- Nếu không tìm thấy phương pháp phù hợp, hoặc nếu tên là "" hoặc ""
đặt trường
public static void đặt trường(Object invokeObject, String fieldName, Object value) throws IllegalAccessException, NoSuchFieldException
- Giá trị "value" được lưu trữ trong trường có tên "fieldName" của đối tượng "invokeObject" sẽ được thực thi.
-
- Thông số:
InvokeObject- Đối tượng cần được thực thiTên trường– Tên trường của đối tượng cần được thực thiKhuyến khích– Giá trị cần thiết lập- ngoại lệ:
Ngoại lệ truy cập bất hợp pháp– Đối tượng được chỉ định là trường cơ sở (hoặc lớp con hoặc lớp triển khai của nó).
Nếu nó không phải là một thể hiện của lớp hoặc giao diện khai báo nó, hoặc nếu quá trình chuyển đổi giải nén thất bại.NoSuchFieldException- Nếu không tìm thấy trường có tên được chỉ định
getField
public static Object getField(Object invokeObject, String fieldName) throws IllegalAccessException, NoSuchFieldException
- Thao tác này truy xuất giá trị của trường có tên "fieldName" của đối tượng "invokeObject" đang được thực thi.
-
- Thông số:
InvokeObject- Đối tượng cần được thực thiTên trường– Tên trường của đối tượng cần được thực thi- Giá trị trả về:
- Giá trị trả về
- ngoại lệ:
Ngoại lệ truy cập bất hợp pháp– Đối tượng được chỉ định là trường cơ sở (hoặc lớp con hoặc lớp triển khai của nó).
Nếu nó không phải là một thể hiện của lớp hoặc giao diện khai báo nó, hoặc nếu quá trình chuyển đổi giải nén thất bại.NoSuchFieldException- Nếu không tìm thấy trường có tên được chỉ định
có trường
public static boolean có trường(Object object, String fieldName) throws Exception
- Điều này kiểm tra xem đối tượng "object" đã khai báo một trường có tên là "fieldName" hay chưa.
-
- Thông số:
sự vật- Đối tượng cần kiểm traTên trường– Tên của khu vực cần kiểm tra- Giá trị trả về:
- Nếu được khai báo, thì đúng.
- ngoại lệ:
Ngoại lệ
GETALLFields
public static java.util.TreeSet GETALLFields(Đối tượng object) ném ra ngoại lệ
-
- Thông số:
sự vật–- Giá trị trả về:
- ngoại lệ:
Ngoại lệ
getShortClassName
public static String getShortClassName(Đối tượng đối tượng)
- Thao tác này truy xuất tên lớp không đủ điều kiện từ một đối tượng.
-
- Thông số:
sự vật–- Giá trị trả về:
getShortClassName
public static String getShortClassName(String className)
- Thao tác này trích xuất tên lớp từ tên đầy đủ.
-
- Thông số:
tên lớp–- Giá trị trả về:
GETFieldName
public static String GETFieldName(Tên phương thức chuỗi)
- Hãy đổi tên trường từ tên phương thức. Việc này phải tuân theo quy ước của JavaBeans.
-
- Thông số:
tên dữ liệu–- Giá trị trả về:
isClassExist
public static boolean isClassExist(String className)
- Thao tác này kiểm tra xem tên đầy đủ "className" có phải là tên lớp đã tồn tại hay không.
-
- Thông số:
tên lớp–- Giá trị trả về:
getPropertyDescriptors
public static PropertyDescriptor[] getPropertyDescriptors(Đối tượng object) ném ra IntrospectionException
- Phương thức này trả về một PropertyDescriptor chứa thông tin đối tượng cho "object".
-
- Thông số:
sự vật–- Giá trị trả về:
- ngoại lệ:
java.beans.IntrospectionException
Mã nguồn BeanUtil
/**
* Một lớp tiện ích giúp dễ dàng sử dụng API phản chiếu của Java.
*/
public class BeanUtil {
/** */
private static final String GET = “GET”;
/** */
private static final String SET = “SET”;
// ———————————————————-『newInstance』
/**
* Tạo và trả về một thể hiện từ chuỗi "className".
* @param className Tên lớp đầy đủ
* @return Một thể hiện mới của tên lớp đủ điều kiện
* @throws Exception
*/
public static Object newInstance(String className) throws Exception {
thử {
return Class.forName(className).newInstance();
} catch (NoClassDefFoundError e) {
System.err.println(“NoClassDefFoundError : ” + className);
ba chữ e;
}
}
/**
* Tạo và trả về một thể hiện từ chuỗi "className".
* @param className Tên lớp đầy đủ
* @param argObj Tham số của hàm tạo
* @return Một thể hiện mới của tên lớp đủ điều kiện
* @throws Exception
*/
public static Object newInstance(String className, Object[] argObj)
ném ngoại lệ {
Class[] argClass = new Class[argObj.length];
for (int i = 0; i < argObj.length; i++) {
argClass[i] = argObj[i].getClass();
}
Constructor c = Class.forName(className).getConstructor(argClass);
return c.newInstance(argObj);
}
/**
* Tạo và trả về một thể hiện từ lớp "clazz".
* @param clazz class
* @return Một phiên bản mới của Sunazz
* @throws Exception
*/
public static Object newInstance(Class clazz) throws Exception {
return clazz.newInstance();
}
/**
* Tạo và trả về một thể hiện từ lớp "clazz".
* @param clazz class
* @param argObj Tham số của hàm tạo
* @return Một phiên bản mới của Sunazz
* @throws Exception
*/
public static Object newInstance(Class clazz, Object[] argObj)
ném ngoại lệ {
Class[] argClass = new Class[argObj.length];
for (int i = 0; i < argObj.length; i++) {
argClass[i] = argObj[i].getClass();
}
Constructor c = clazz.getConstructor(argClass);
return c.newInstance(argObj);
}
// ---------------------"Phương pháp"
/**
* Phương thức thiết lập (setter) của trường "fieldName" của đối tượng "invokeObject"
* Gọi và lưu trữ giá trị "value".
* <br>
* Nếu không có phương thức setter, giá trị sẽ được gán trực tiếp cho trường đó.
Tuy nhiên, trong trường hợp này, thuộc tính cần sửa đổi phải là public.
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên thuộc tính của đối tượng cần được thực thi.
* @param value Giá trị cần thiết lập
* @throws Exception Ngoại lệ sau sẽ xảy ra:
* @throwsInvocationTargetException khi phương thức cơ bản ném ra một ngoại lệ
* @throws IllegalAccessException Đối tượng Method này là Java
* Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.
* @throwsNoSuchMethodException nếu không tìm thấy phương thức có tên được chỉ định.
*/
public static void setProperty(Object invokeObject, String fieldName,
Giá trị đối tượng) ném ra ngoại lệ {
thử {
Phương thức method = searchMethod(invokeObject, fieldName, SET);
Class[] paramClasses = method.getParameterTypes();
Object[] valueArray = null;
nếu (paramClasses[0].isInstance(value)) {
// Nếu đối tượng được thiết lập là lớp con của lớp đối số, nó sẽ không được chuyển đổi.
valueArray = new Object[] { value };
khác {
valueArray = new Object[] { convObject(value, paramClasses[0]
.getName()) };
}
method.invoke(invokeObject, valueArray);
} catch (NoSuchMethodException e) {
thử {
// Nếu không có phương thức setter, hãy thiết lập trực tiếp cho trường đó.
setField(invokeObject, fieldName, value);
} catch (NoSuchFieldException fe) {
String errorMes = “\nClass” + getShortClassName(invokeObject)
+ “dành cho trường `` + Tên trường ``''\n”
+ "Không có phương thức thiết lập nào có thể truy cập được."“
+ “Trường” + Tên trường
" + "" cũng không được công khai.;
ném ngoại lệ IllegalAccessException mới (errorMes);
}
}
}
/**
* Phương thức getter của fieldName của đối tượng invokeObject
* Truy xuất giá trị cuộc gọi. <br>
* Nếu không có phương thức getter, giá trị sẽ được lấy trực tiếp từ trường.
Tuy nhiên, trong trường hợp này, thuộc tính cần sửa đổi phải là public.
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên thuộc tính của đối tượng cần được thực thi.
* @return Giá trị trả về của phương thức getter
* @throws Exception Ngoại lệ sau sẽ xảy ra:
* @throwsInvocationTargetException khi phương thức cơ bản ném ra một ngoại lệ
* @throws IllegalAccessException Đối tượng Method này là Java
* Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.
* @throwsNoSuchFieldException nếu không tìm thấy trường có tên được chỉ định.
*/
public static Object getProperty(Object invokeObject, String fieldName)
ném ngoại lệ {
thử {
Phương thức method = searchMethod(invokeObject, fieldName, GET);
return method.invoke(invokeObject, null);
} catch (NoSuchMethodException e) {
return getField(invokeObject, fieldName);
}
}
/**
* Thực thi phương thức "callMethod" của đối tượng "invokeObject".
* Nếu có giá trị trả về, giá trị đó có thể được lấy dưới dạng một đối tượng.
* @param invokeObject Đối tượng cần gọi.
* @param callMethod Tên của phương thức cần được thực thi
* @param argObjects Nếu có các tham số, hãy truyền chúng dưới dạng một mảng các đối tượng.
* Nếu không cung cấp đối số nào, giá trị null sẽ được truyền vào.
* @return Giá trị trả về khi thực thi phương thức "callMethod"
* @throwsInvocationTargetException khi phương thức cơ bản ném ra một ngoại lệ
* @throws IllegalAccessException Đối tượng Method này là Java
* Nếu cơ chế kiểm soát truy cập ngôn ngữ được triển khai và phương thức cơ bản không thể truy cập được.
* @throwsNoSuchMethodException nếu không tìm thấy phương thức có tên được chỉ định.
*/
public static Object invoke(Object invokeObject, String callMethod,
Object[] argObjects) ném InvocationTargetException,
IllegalAccessException, NoSuchMethodException {
Phương thức method = findMethod(invokeObject, callMethod, argObjects);
return method.invoke(invokeObject, argObjects);
}
/**
* Tìm kiếm phương thức "callMethod" của đối tượng "invokeObject".
* @param invokeObject Đối tượng cần gọi.
* @param callMethod Tên phương thức của đối tượng cần được thực thi
* @param argObjects Nếu có các tham số, hãy truyền chúng dưới dạng một mảng các đối tượng.
* Nếu không cung cấp đối số nào, giá trị null sẽ được truyền vào.
* @return Một đối tượng Phương thức khớp với các điều kiện của đối số được chỉ định.
* @throwsNoSuchMethodException nếu không tìm thấy phương thức phù hợp.
* Hoặc tên là “ " hoặc " "trong trường hợp của
*/
public static Method findMethod(Object invokeObject, String callMethod,
Object[] argObjects) throws NoSuchMethodException {
Class[] paramClasses = null;
Method[] methods = invokeObject.getClass().getMethods();
top: for (int i = 0; i < methods.length; i++) {
nếu (methods[i].getName().equals(callMethod)) {
nếu (argObjects == null)
&& methods[i].getParameterTypes().length == 0) {
trả về các phương thức[i];
}
nếu (argObjects == null) {
Tiếp tục;
}
paramClasses = methods[i].getParameterTypes();
if (paramClasses.length == argObjects.length) {
// Kiểm tra tính hợp lệ của kiểu dữ liệu của tất cả các danh sách tham số và đối số.
for (int j = 0; j < paramClasses.length; j++) {
Lớp paramClass = paramClasses[j];
Object argObj = argObjects[j];
// Nếu kiểu dữ liệu của đối số là kiểu nguyên thủy, thì đối tượng đối số sẽ là...
// không phải là null mà là một kiểu dữ liệu nguyên thủy
// Hoặc, bất kỳ lớp con nào của Number đều được chấp nhận.
nếu (argObj == null) {
Tiếp tục;
}
nếu (paramClass.isPrimitive()
&& (argObj instanceof Number || argObj
.getClass().isPrimitive())) {
Tiếp tục;
}
nếu (!paramClass.isInstance(argObj)) {
// Nếu không có sự tương thích chuyển đổi ngầm định giữa các kiểu dữ liệu, hãy chuyển sang phương thức tiếp theo.
Tiếp tục lên đầu trang;
}
}
trả về các phương thức[i];
}
}
}
String paramLength = (paramClasses != null) ? Integer
.toString(paramClasses.length) : “”;
String errorMes = getShortClassName(invokeObject) + "Phương thức"“
+ callMethod + “はありません。” + “[ paramClasses.length ] = ”
+ paramLength + “,[ argObjects.length ] = ” + argObjects.length
+ “”;
ném ngoại lệ NoSuchMethodException mới (errorMes);
}
// ----------------------"Cánh đồng"
/**
* Giá trị của trường có tên "fieldName" của đối tượng cần thực thi "invokeObject" được thiết lập.
* Lưu trữ giá trị.
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên trường của đối tượng cần được thực thi.
* @param value Giá trị cần thiết lập
* @throws IllegalAccessException Đối tượng được chỉ định dựa trên
* Một trường (hoặc lớp con hoặc phần triển khai của nó)
* Nếu nó không phải là một thể hiện của lớp hoặc giao diện khai báo *
* Hoặc nếu quá trình chuyển đổi giải nén thất bại
* @throwsNoSuchFieldException nếu không tìm thấy trường có tên được chỉ định.
*/
public static void setField(Object invokeObject, String fieldName,
Giá trị đối tượng) ném ra ngoại lệ IllegalAccessException, NoSuchFieldException {
Field field = searchField(invokeObject, fieldName);
String className = field.getType().getName();
Object convObj = null;
nếu (field.getType().isInstance(value)) {
convObj = giá trị;
khác {
convObj = convObject(value, className);
}
field.set(invokeObject, convObj);
}
/**
* Giá trị của tên trường "fieldName" của đối tượng cần được thực thi "invokeObject"
* Lấy nó ra.
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên trường của đối tượng cần được thực thi.
* @return Giá trị trả về
* @throws IllegalAccessException Đối tượng được chỉ định dựa trên
* Một trường (hoặc lớp con hoặc phần triển khai của nó)
* Nếu nó không phải là một thể hiện của lớp hoặc giao diện khai báo *
* Hoặc nếu quá trình chuyển đổi giải nén thất bại
* @throwsNoSuchFieldException nếu không tìm thấy trường có tên được chỉ định.
*/
public static Object getField(Object invokeObject, String fieldName)
ném ra ngoại lệ IllegalAccessException, NoSuchFieldException {
Field field = searchField(invokeObject, fieldName);
trả về trường.get(invokeObject);
}
/**
* Liệu đối tượng "object" có khai báo tên trường "fieldName" hay không
Tôi sẽ kiểm tra.
* @param object Đối tượng cần kiểm tra
* @param fieldName Tên của trường cần kiểm tra
* Nếu @return được khai báo, thì đúng.
* @throws Exception
*/
public static boolean hasField(Object object, String fieldName)
ném ngoại lệ {
PropertyDescriptor[] props = getPropertyDescriptors(object);
for (int i = 0; i < props.length; i++) {
Chuỗi _fieldName = props[i].getName();
nếu (fieldName.equals(_fieldName)) {
Trả về giá trị đúng;
}
}
Trả về false;
}
/**
*
* @param object
* @trở lại
* @throws Exception
*/
public static TreeSet getAllFields(Object object) throws Exception {
TreeSet fieldSet = new TreeSet();
// Lấy tên thuộc tính từ phương thức
PropertyDescriptor[] props = getPropertyDescriptors(object);
for (int i = 0; i < props.length; i++) {
String fieldName = props[i].getName();
fieldSet.add(fieldName);
}
// Lấy tên thuộc tính từ trường
Field[] fields = object.getClass().getFields();
for (int i = 0; i < fields.length; i++) {
String fieldName = fields[i].getName();
nếu (!fieldSet.contains(fieldName)) {
fieldSet.add(fieldName);
}
}
Trả về fieldSet;
}
/**
*
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên trường của đối tượng cần được thực thi.
* @return Một đối tượng Fielded khớp với điều kiện của đối số được chỉ định.
* @throwsNoSuchFieldException nếu không tìm thấy trường có tên được chỉ định.
*/
private static Field searchField(Object invokeObject, String fieldName)
ném ra ngoại lệ NoSuchFieldException {
thử {
return invokeObject.getClass().getField(fieldName);
} catch (NoSuchFieldException e) {
// Phạm vi này được lấy từ tên cột của bảng.
fieldName = checkFieldName(fieldName);
Field[] fields = invokeObject.getClass().getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equalsIgnoreCase(fieldName)) {
trả về các trường[i];
}
}
ném ngoại lệ NoSuchFieldException mới (fieldName);
}
}
// ----------------------" người khác "
/**
* Truy xuất tên lớp không đủ điều kiện từ một đối tượng.
* @param object
* @trở lại
*/
public static String getShortClassName(Object object) {
nếu (đối tượng == null) {
Trả về "null";
}
Tên chuỗi = object.getClass().getName();
trả về getShortClassName(name);
}
/**
* Truy xuất tên lớp từ tên đầy đủ.
* @param className
* @trở lại
*/
public static String getShortClassName(String className) {
int index = className.lastIndexOf(“.”);
return className.substring(index + 1);
}
/**
* Thay đổi tên trường từ tên phương thức. Điều này tuân theo quy ước của JavaBeans.
* Điều này là bắt buộc.
* @param knowledgeName
* @trở lại
*/
public static String getFieldName(String methodName) {
String fieldName = null;
nếu (methodName.startsWith(“is”)) {
fieldName = methodName.substring(2);
khác {
fieldName = methodName.substring(3);
}
fieldName = convString(fieldName, 0, “L”);
Trả về FieldName;
}
/**
* Đoạn mã này kiểm tra xem tên đầy đủ "className" có phải là tên lớp đã tồn tại hay không.
* @param className
* @trở lại
*/
public static boolean isClassExist(String className) {
thử {
Class.forName(className);
Trả về giá trị đúng;
} catch (Exception e) {
Trả về false;
}
}
private final static Map beanInfoCache = new HashMap();
/**
* Trả về một PropertyDescriptor chứa thông tin đối tượng của "object".
* @param object
* @trở lại
* @throwsIntrospectionException
*/
public static PropertyDescriptor[] getPropertyDescriptors(Object object)
ném IntrospectionException {
BeanInfo beanInfo = (BeanInfo) beanInfoCache.get(object.getClass());
nếu (beanInfo == null) {
beanInfo = Introspector.getBeanInfo(object.getClass());
beanInfoCache.put(object.getClass(), beanInfo);
}
// BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
return beanInfo.getPropertyDescriptors();
}
// ————————————————————————–
// ———————————————『Sau đây là một phương thức riêng tư』
// ————————————————————————–
/**
* Phương thức truy cập cho đối số fieldName được tìm kiếm dựa trên PropertyDescriptor.
* @param invokeObject Đối tượng cần gọi.
* @param fieldName Tên trường
* @param type Phương thức getter ⇒ GET Phương thức getter ⇒ SET
* @return Một đối tượng Phương thức khớp với các điều kiện của đối số được chỉ định.
* @throwsNoSuchMethodException nếu không tìm thấy phương thức phù hợp.
* Hoặc tên là “ " hoặc " "”
* trong trường hợp của
* @throwsIntrospectionException
*/
private static Method searchMethod(Object invokeObject, String fieldName,
Kiểu chuỗi) ném ra ngoại lệ NoSuchMethodException, IntrospectionException {
Hàm phương thức = null;
fieldName = checkFieldName(fieldName);
PropertyDescriptor[] props = getPropertyDescriptors(invokeObject);
for (int i = 0; i < props.length; i++) {
String name = props[i].getName();
nếu (!name.equalsIgnoreCase(fieldName)) {
Tiếp tục;
}
nếu (type.equals(GET)) {
phương thức = props[i].getReadMethod();
khác {
phương thức = props[i].getWriteMethod();
}
nếu (phương thức == null) {
Tiếp tục;
}
trả về phương thức;
}
// Nếu phương thức không tồn tại.
ném ngoại lệ NoSuchMethodException mới ("Lớp này không có phương thức đó.")“
+ “(Không phân biệt chữ hoa chữ thường.):” + type.toLowerCase()
+ convString(fieldName, 0, “U”) + “()”);
}
/**
* Kiểm tra xem đối số fieldName có phải là tên cột hay không, và nếu đúng thì đó là tên cột.
Tôi sẽ chuyển đổi lại.
*
* ĐỊA CHỈ THƯ ⇒ ĐỊA CHỈ THƯ ↓ mailaddress = mailAddress
* @param fieldName Tên trường hoặc tên cột
* Tên trường @return
*/
private static String checkFieldName(String fieldName) {
int index = fieldName.indexOf(“_”);
trong khi (đúng) {
nếu (chỉ số == -1) {
Trả về FieldName;
}
StringBuffer convcloumn = new StringBuffer(fieldName);
convcloumn.deleteCharAt(index);
fieldName = convcloumn.toString();
index = fieldName.indexOf(“_”);
}
}
/**
* Chuyển đổi đối tượng cần chuyển đổi sang kiểu dữ liệu được chỉ định bởi convClassName.
*
* @param object Đối tượng cần chuyển đổi
* @param convClassName Chuỗi lớp của kiểu dữ liệu cần chuyển đổi.
* @return đối tượng đã chuyển đổi
*/
private static Object convObject(Object object, String convClassName) {
nếu (đối tượng == null) {
// Việc chuyển đổi sang kiểu dữ liệu nguyên thủy sẽ gây ra lỗi nếu nó trả về null.
// Quấn nó quanh số 0.
nếu (convClassName.equals(“int”)) {
trả về số nguyên mới (0);
} else if (convClassName.equals(“long”)) {
trả về long mới (0);
khác {
trả về null;
}
}
nếu (object.getClass().getName().equals(convClassName)) {
Trả về đối tượng;
}
// —————————————-『 object instanceof String 』
if (object instanceof String) {
if (convClassName.equals(“java.lang.String”)) {
Trả về đối tượng;
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
Chuỗi str = (Chuỗi) đối tượng;
nếu (isExist(str)) {
// Sẽ không hoạt động trừ khi bạn chuyển đổi nó sang định dạng BigDecimal trước.
// 1000.00000
BigDecimal big = new BigDecimal(str);
trả về Long mới (big.longValue());
khác {
// Nếu str là một chuỗi ký tự cố định, giá trị ban đầu là "0".
trả về long mới (0);
}
} else if (convClassName.equals(“java.sql.Date”)) {
trả về đối tượng toSqlDate((String));
} else if (convClassName.equals(“java.sql.Timestamp”)) {
Ngày tháng = toSqlDate((String) object);
trả về dấu thời gian mới (ngày.getTime());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
// Nếu str là một chuỗi ký tự cố định, giá trị ban đầu là "0".
Chuỗi str = (Chuỗi) đối tượng;
nếu (isExist(str)) {
BigDecimal big = new BigDecimal(str);
return new Integer(big.intValue());
khác {
trả về số nguyên mới (0);
}
} else if (convClassName.equals(“boolean”)) {
return Boolean.valueOf(object.toString());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
Chuỗi tạm thời = ((chuỗi) đối tượng).trim();
// temp.length() == 0の場合0ではなくnullにするのが無難。
if (temp.length() == 0) {
trả về null;
khác {
trả về BigDecimal mới(temp);
}
}
throwNoSupprt(object, convClassName);
}
// ———————————『 object instanceof java.sql.Date 』
else if (object instanceof java.sql.Date) {
if (convClassName.equals(“java.lang.String”)) {
return toStringDate((java.sql.Date) object, “yyyy/MM/dd”);
} else if (convClassName.equals(“java.sql.Date”)) {
Trả về đối tượng;
} else if (convClassName.equals(“java.sql.Timestamp”)) {
return new Timestamp(((Date) object).getTime());
}
throwNoSupprt(object, convClassName);
}
// ————————————-『 object instanceof Timestamp 』
else if (object instanceof Timestamp) {
thời gian dài = ((Timestamp) object).getTime();
if (convClassName.equals(“java.lang.String”)) {
return toStringDate(time, “yyyy/MM/dd HH:mm:ss”);
} else if (convClassName.equals(“java.sql.Date”)) {
trả về new java.sql.Date(time);
} else if (convClassName.equals(“java.sql.Timestamp”)) {
Trả về đối tượng;
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof Integer 』
else if (object instanceof Integer) {
nếu (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
Trả về đối tượng;
} else if (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
return new Long(((Integer) object).longValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
return new BigDecimal(((Integer) object).intValue());
}
throwNoSupprt(object, convClassName);
}
// ——————————————『 object instanceof Long 』
else if (object instanceof Long) {
nếu (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
Trả về đối tượng;
} else if (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
return new Integer(((Long) object).intValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
return new BigDecimal(((Long) object).longValue());
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof Double 』
else if (object instanceof Double) {
if (convClassName.equals(“java.lang.String”)) {
// SỐ CỘT (8,0)
// Windows Oracle > BigDecimal
// Oracle UNIX > Double
BigDecimal big = new BigDecimal(((Double) object).doubleValue());
int scale = big.scale();
nếu (scale == 0) {
return big.toString();
khác {
// Chức năng làm tròn số không được hỗ trợ nếu cần thiết.
throwNoSupprt(object, convClassName);
}
}
nếu (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
return new Integer(((Double) object).intValue());
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
return new Long(((Double) object).longValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
return new BigDecimal(((Double) object).doubleValue());
}
throwNoSupprt(object, convClassName);
}
// ————————————『 object instanceof BigDecimal 』
else if (object instanceof BigDecimal) {
if (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
return new Long(((BigDecimal) object).longValue());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
return new Integer(((BigDecimal) object).intValue());
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof byte[] 』
else if (object instanceof byte[]) {
nếu (convClassName.equals(“java.sql.Blob”)) {
Trả về đối tượng;
}
throwNoSupprt(object, convClassName);
}
// ————————————————『Đối tượng là kiểu Boolean』
else if (object instanceof Boolean) {
nếu (convClassName.equals(“boolean”)) {
Trả về đối tượng;
}
throwNoSupprt(object, convClassName);
}
// ———————————————-『object is a boolean[]』
else if (object instanceof boolean[]) {
if (convClassName.equals(“java.lang.String”)) {
boolean[] bs = (boolean[]) object;
StringBuffer buff = new StringBuffer(“[“);
for (int i = 0; i < bs.length; i++) {
buff.append(bs[i] + ",");
}
buff.deleteCharAt(buff.length() – 1);
buff.append("]");
return buff.toString();
}
throwNoSupprt(object, convClassName);
}
throwNoSupprt(object, convClassName);
trả về null;
}
/**
* Ngoại lệ này được ném ra nếu quá trình chuyển đổi không được hỗ trợ.
*
* @param object Đối tượng cần chuyển đổi
* @param convClassName Kiểu dữ liệu cần chuyển đổi sang
*/
private static void throwNoSupprt(Object object, String convClassName) {
String className = (object != null) ? object.getClass().getName()
: "vô giá trị";
String errorMess = "\nViệc chuyển đổi kiểu dữ liệu cho đối tượng này hiện chưa được hỗ trợ.\n"“
+ ” [ Đối tượng ] = ” + đối tượng + “,[ Loại đối tượng ] = ” + className
+ “,[convertClass] = ” + convClassName + “”;
ném ngoại lệ UnsupportedOperationException mới (errorMess);
}
/**
* Chuyển đổi ký tự tại vị trí [index] trong chuỗi [str] thành chữ hoa hoặc chữ thường.
* <p>
* @param str Chuỗi cần được đánh giá
* @param index Chỉ định vị trí
* @param toCase Chuyển đổi thành chữ hoa ⇒ U | u Chuyển đổi thành chữ thường ⇒ L | l
* @return chuỗi đã chuyển đổi
*/
private static String convString(String str, int index, String toCase) {
if (str == null || str.trim().length() == 0) {
trả về chuỗi;
khác {
String temp = str.substring(index, index + 1);
nếu (toCase.equalsIgnoreCase(“u”)) {
temp = temp.toUpperCase();
khác {
temp = temp.toLowerCase();
}
StringBuffer tempBuffer = new StringBuffer(str);
tempBuffer.replace(index, index + 1, temp);
return tempBuffer.toString();
}
}
/**
* Thao tác này xác minh xem [giá trị] có phải là một giá trị hợp lệ hay không.
*
* @param value Chuỗi cần được đánh giá
* @return [true]: Nếu không rỗng và không phải là ""
*/
private static boolean isExist(String value) {
if (value != null && value.length() != 0) {
Trả về giá trị đúng;
}
Trả về false;
}
/**
* Lớp java.util.Date hoặc lớp con của nó theo định dạng được chỉ định
* Chuyển đổi thành chuỗi ký tự.
* @param date Lớp javautil.Date cần chuyển đổi thành
* @param pattern Chỉ định định dạng
* @trả về một chuỗi ngày tháng được định dạng
*/
private static String toStringDate(Date date, String pattern) {
SimpleDateFormat sdFormat = new SimpleDateFormat(pattern);
return sdFormat.format(date);
}
private static java.sql.Date toSqlDate(String strDate) {
Calendar cal = toCalendar(strDate);
trả về toSqlDate(cal);
}
private static java.sql.Date toSqlDate(Calendar cal) {
long l = cal.getTime().getTime();
trả về new java.sql.Date(l);
}
/**
* Chuyển đổi giá trị thời gian dài thành chuỗi theo định dạng được chỉ định.
* @param time Một giá trị kiểu long biểu thị thời gian hiện tại tính bằng mili giây.
* @param pattern Chỉ định định dạng
* @trả về một chuỗi ngày tháng được định dạng
*/
private static String toStringDate(long time, String pattern) {
trả về chuỗi ngày (mới ngày (thời gian), mẫu);
}
/**
* Chuỗi ⇒ java.sql.Date
*
* Chuyển đổi chuỗi ngày tháng sau thành đối tượng java.sql.Date
* yyyy/MM/dd HH:mm:ss.SSS yyyy-MM-dd HH:mm:ss.SSS
*
* “20030407” “2003/04/07” “2003-04-07” “2003/04/07 15:20:16” “2003-04-07
* 15:20:16”
* @param strDate
* @trở lại
*/
private static Calendar toCalendar(String strDate) {
strDate = format(strDate);
Calendar cal = Calendar.getInstance();
int yyyy = Integer.parseInt(strDate.substring(0, 4));
int MM = Integer.parseInt(strDate.substring(5, 7));
int dd = Integer.parseInt(strDate.substring(8, 10));
int HH = cal.get(Calendar.HOUR_OF_DAY);
int mm = cal.get(Calendar.MINUTE);
int ss = cal.get(Calendar.SECOND);
int SSS = cal.get(Calendar.MILLISECOND);
cal.clear();
cal.set(yyyy, MM – 1, dd);
int len = strDate.length();
công tắc (len) {
Trường hợp 10:
phá vỡ;
trường hợp 16: // yyyy/MM/dd HH:mm
HH = Integer.parseInt(strDate.substring(11, 13));
mm = Integer.parseInt(strDate.substring(14, 16));
cal.set(Calendar.HOUR_OF_DAY, HH);
cal.set(Calendar.MINUTE, mm);
phá vỡ;
trường hợp 19: // yyyy/MM/dd HH:mm:ss
HH = Integer.parseInt(strDate.substring(11, 13));
mm = Integer.parseInt(strDate.substring(14, 16));
ss = Integer.parseInt(strDate.substring(17, 19));
cal.set(Calendar.HOUR_OF_DAY, HH);
cal.set(Calendar.MINUTE, mm);
cal.set(Calendar.SECOND, ss);
phá vỡ;
trường hợp 23: // yyyy/MM/dd HH:mm:ss.SSS
HH = Integer.parseInt(strDate.substring(11, 13));
mm = Integer.parseInt(strDate.substring(14, 16));
ss = Integer.parseInt(strDate.substring(17, 19));
SSS = Integer.parseInt(strDate.substring(20, 23));
cal.set(Calendar.HOUR_OF_DAY, HH);
cal.set(Calendar.MINUTE, mm);
cal.set(Calendar.SECOND, ss);
cal.set(Calendar.MILLISECOND, SSS);
phá vỡ;
mặc định:
ném ngoại lệ IllegalStateException mới(
“"Chuỗi ký tự này không thể chuyển đổi thành chuỗi ngày tháng:"”
+ strDate);
}
trả về cal;
}
/**
* Bất kỳ chuỗi ngày tháng nào cũng có thể ở định dạng "yyyy/MM/dd" hoặc "yyyy/MM/dd HH:mm:ss"
* Đang cố gắng chuyển đổi sang định dạng khác.
* Ví dụ: 03/1/3 ⇒ 2003/01/03
* @param strDate
* @trở lại
*/
private static String format(String strDate) {
strDate = strDate.trim();
Chuỗi yyyy = null;
Chuỗi MM = null;
Chuỗi dd = null;
Chuỗi HH = null;
Chuỗi mm = null;
Chuỗi ss = null;
Chuỗi SSS = null;
// Nếu không có dấu "-" hoặc "/"
if (strDate.indexOf(“/”) == -1 && strDate.indexOf(“-“) == -1) {
if (strDate.length() == 8) {
yyyy = strDate.substring(0, 4);
MM = strDate.substring(4, 6);
dd = strDate.substring(6, 8);
return yyyy + “/” + MM + “/” + dd;
khác {
yyyy = strDate.substring(0, 4);
MM = strDate.substring(4, 6);
dd = strDate.substring(6, 8);
HH = strDate.substring(9, 11);
mm = strDate.substring(12, 14);
ss = strDate.substring(15, 17);
return yyyy + “/” + MM + “/” + dd + ” ” + HH + “:” + mm + “:”
+ ss;
}
}
StringTokenizer token = new StringTokenizer(strDate, “_/-:. “);
StringBuffer result = new StringBuffer();
for (int i = 0; token.hasMoreTokens(); i++) {
Chuỗi tạm thời = token.nextToken();
công tắc (i) {
trường hợp 0 phần năm
yyyy = fillString(strDate, temp, “f”, “20”, 4);
result.append(yyyy);
phá vỡ;
trường hợp 1 phần tháng
MM = fillString(strDate, temp, “f”, “0”, 2);
result.append("/" + MM);
phá vỡ;
trường hợp 2 một phần của ngày
dd = fillString(strDate, temp, “f”, “0”, 2);
result.append("/" + dd);
phá vỡ;
trường hợp 3:// phần thời gian
HH = fillString(strDate, temp, “f”, “0”, 2);
result.append(" " + HH);
phá vỡ;
trường hợp 4:// phần
mm = fillString(strDate, temp, “f”, “0”, 2);
result.append(":" + mm);
phá vỡ;
trường hợp 5:// phần về giây
ss = fillString(strDate, temp, “f”, “0”, 2);
result.append(":" + ss);
phá vỡ;
trường hợp 6:// phần mili giây
SSS = fillString(strDate, temp, “b”, “0”, 3);
result.append("." + SSS);
phá vỡ;
}
}
return result.toString();
}
private static String fillString(String strDate, String str,
Vị trí chuỗi, chuỗi addStr, độ dài số nguyên) {
if (str.length() > len) {
String mes = strDate + "Chuỗi này không thể chuyển đổi thành chuỗi ngày tháng";
ném ngoại lệ IllegalStateException mới(mes);
}
return fillString(str, position, addStr, len);
}
/**
* Chuỗi cần thêm vào chuỗi [str] được đặt vào vị trí [position] và sau đó là [len].
* Cho vào cho đến khi đầy.
* <p>
* Ví dụ: String ss = StringUtil.fillString(“aaa”,”b”,”0″,7); ss ⇒ “aaa0000”
*
*Lưu ý: hàm fillString() chèn chuỗi cho đến khi đạt đến độ dài len, trong khi hàm addString() chèn các chuỗi có độ dài bằng len.
*
* @param str Chuỗi mục tiêu
* @param position Chèn trước ⇒ F/f Chèn sau ⇒ B/b
* @param addStr Chuỗi cần chèn
* @param len Số chữ số cần cộng
* @return Chuỗi đã được chuyển đổi. Nếu [str] là null hoặc một chuỗi rỗng, [addStr] sẽ được chuyển đổi thành [len].
* Trả về kết quả của các thao tác chèn cho đến khi điều kiện được đáp ứng.
*/
private static String fillString(String str, String position,
Chuỗi addStr, số nguyên len) {
StringBuffer tempBuffer = null;
nếu (!isExist(str)) {
tempBuffer = new StringBuffer();
for (int i = 0; i < len; i++) {
tempBuffer.append(addStr);
}
return tempBuffer.toString();
} else if (str.length() != len) {
tempBuffer = new StringBuffer(str);
while (len > tempBuffer.length()) {
nếu (position.equalsIgnoreCase(“f”)) {
tempBuffer.insert(0, addStr);
khác {
tempBuffer.append(addStr);
}
}
return tempBuffer.toString();
}
trả về chuỗi;
}
}
