Java 反射很容易實作。
Javaの反射本節介紹讓 API 使用更便利的實用類別。
什麼是反射?
反射 API“牙齒,”java.lang.reflect它包含在包裝內。
此 API 從 Java 類別中檢索欄位和方法等資訊。
我們將主要使用以下類別。
- java.lang.Class
- java.lang.reflect.Constructor
- java.lang.reflect.Method
- java.lang.reflect.field
反射使用這種方法,您可以避免直接編寫類別建立和方法呼叫的程式碼。
你可以建立類別實例並從字串執行方法。
透過在 XML 等外部檔案中定義類別名稱和方法名,應用程式可以動態地適應執行時間環境的變化。
此外,它也是一個非常有效的API,可用於建立高度靈活的應用程式。
反思的目的
反射雖然用戶不常直接使用它,
它廣泛應用於 Struts 等 Web 應用程式和 O/R 映射等框架中。
例如,當您想要自動將網頁畫面上的輸入資料設定到 JavaBeans 屬性時,
例如,在發出 SQL 查詢以自動更新 JavaBeans 屬性時,就會使用這種方法。
此外,還提供動態載入和註冊外掛程式等功能,以便在應用程式啟動時擴展其功能。反射使用[這種方法]可以輕鬆實現這一點。
執行範例
現在,請運行範例程式碼,親自體驗基於框架的程式設計。
這裡我們將使用以下類別反射這展示了該工具的簡單使用方法。
Main.java要執行的類別
BeanUtil.java反射實用類
FreeSoft.java……這是一個代表自由軟體的類,用作反射。
●依常規方式執行
FreeSoft freeSoft = new FreeSoft();
freeSoft.setName(聊天和即時通訊——也支援聊天和即時通訊!!)“);
freeSoft.showName();
freeSoft.showPrice(0);
●使用反射執行時
// 建立 FreeSoft 類別的實例
Object invokeObject = BeanUtil.newInstance(「FreeSoft」)“);
// 為名稱欄位設定值。
BeanUtil.setProperty(invokeObject, “姓名” , “聊天和即時通訊——聊天和即時通訊也一樣!!”);
// 執行 FreeSoft 的 showName() 方法。
BeanUtil.invoke(invokeObject, “showName”, , 無效的);
// 執行 FreeSoft 的 showPrice() 方法。
// 如果該方法有參數,則必須將它們作為 Object 類型的陣列傳遞。
BeanUtil.invoke(invokeObject, “顯示價格”,new Object[]{new Integer(0)});
●執行結果
無論是否使用反射,執行結果都是一樣的。
軟體名稱:聊天和即時通訊!
價格:0日圓
>>>使用反射時
軟體名稱:聊天和即時通訊!
價格:0日圓
BeanUtil 方法詳情
newInstance
public static Object newInstance(字串類別名)拋出異常
- 這會根據字串“className”建立並傳回一個實例。
-
- 參數:
類別名- 完全限定類別名- 傳回值:
- 完全限定類別名稱的新實例
- 例外:
例外
newInstance
public static Object newInstance(String className, Object[] argObj) 拋出異常
- 這會根據字串“className”建立並傳回一個實例。
-
- 參數:
類別名- 完全限定類別名argObj– 建構函式參數- 傳回值:
- 完全限定類別名稱的新實例
- 例外:
例外
newInstance
public static Object newInstance(類 clazz)拋出異常
- 這會創建並傳回類別“clazz”的一個實例。
-
- 參數:
克拉茲- 班級- 傳回值:
- 克拉茲的新實例
- 例外:
例外
newInstance
public static Object newInstance(Class clazz, Object[] argObj) 拋出異常
- 這會創建並傳回類別“clazz”的一個實例。
-
- 參數:
克拉茲- 班級argObj– 建構函式參數- 傳回值:
- 克拉茲的新實例
- 例外:
例外
設定屬性
public static void 設定屬性(Object invokeObject, String fieldName, Object value) 拋出例外
- 呼叫物件“invokeObject”的欄位「fieldName」的setter方法來儲存值「value」。
如果沒有 setter 方法,則會直接將值賦給欄位。但是,在這種情況下,目標屬性的存取修飾符必須為 public。
-
- 參數:
呼叫對象要執行的對象欄位名– 要執行的物件的屬性名稱受到推崇的– 要設定的值- 例外:
例外– 出現以下異常:呼叫目標異常- 當底層方法拋出異常時非法存取異常此方法物件是 Java
如果實現了語言存取控制,並且無法存取底層方法。NoSuchMethodException- 如果找不到具有指定名稱的方法
取得屬性
public static Object 取得屬性(Object invokeObject, String fieldName) 拋出例外
- 呼叫 invokeObject 物件的 fieldName 的 getter 方法來檢索其值。
如果沒有 getter 方法,則會直接從欄位中取得值。但是,在這種情況下,目標屬性的存取修飾符必須為 public。 -
- 參數:
呼叫對象要執行的對象欄位名– 要執行的物件的屬性名稱- 傳回值:
- Getter 方法傳回值
- 例外:
例外– 出現以下異常:呼叫目標異常- 當底層方法拋出異常時非法存取異常此方法物件是 Java
如果實現了語言存取控制,並且無法存取底層方法。NoSuchFieldException- 如果找不到具有指定名稱的字段
呼叫
public static Object 呼叫(Object invokeObject, String callMethod, Object[] argObjects) 拋出 InvocationTargetException、IllegalAccessException 或 NoSuchMethodException 異常
- 這將執行物件“invokeObject”的“callMethod”方法。
如果有傳回值,可以將其作為物件取得。 -
- 參數:
呼叫對象要執行的對象呼叫方法– 要執行的方法名稱argObjects– 若有參數,則以物件陣列的形式傳遞。如果沒有參數,則傳遞 null 值。- 傳回值:
- 執行“callMethod”的回傳值
- 例外:
呼叫目標異常- 當底層方法拋出異常時非法存取異常此方法物件是 Java
如果實現了語言存取控制,並且無法存取底層方法。NoSuchMethodException- 如果找不到具有指定名稱的方法
尋找方法
public static 方法 尋找方法(Object invokeObject, String callMethod, Object[] argObjects) 拋出 NoSuchMethodException
- 這會尋找物件“invokeObject”的方法“callMethod”。
-
- 參數:
呼叫對象要執行的對象呼叫方法– 要執行的物件的方法名稱argObjects– 若有參數,則以物件陣列的形式傳遞。如果沒有參數,則傳遞 null 值。- 傳回值:
- 符合指定參數條件的方法對象
- 例外:
NoSuchMethodException- 如果找不到符合的方法,或名稱為“”或“”
setField
public static void setField(Object invokeObject, String fieldName, Object value) 拋出 IllegalAccessException, NoSuchFieldException
- 值“value”儲存在要執行的物件“invokeObject”的名為“fieldName”的欄位中。
-
- 參數:
呼叫對象要執行的對象欄位名– 要執行的物件的欄位名稱受到推崇的– 要設定的值- 例外:
非法存取異常– 指定的物件是基底欄位(或其子類別或實作)。
如果它不是聲明它的類別或介面的實例,或者解包轉換失敗。NoSuchFieldException- 如果找不到具有指定名稱的字段
取得字段
public static Object 取得字段(Object invokeObject, String fieldName) 拋出 IllegalAccessException 或 NoSuchFieldException
- 這將檢索目標物件“invokeObject”的欄位名稱“fieldName”的值。
-
- 參數:
呼叫對象要執行的對象欄位名– 要執行的物件的欄位名稱- 傳回值:
- 傳回值
- 例外:
非法存取異常– 指定的物件是基底欄位(或其子類別或實作)。
如果它不是聲明它的類別或介面的實例,或者解包轉換失敗。NoSuchFieldException- 如果找不到具有指定名稱的字段
hasField
公共靜態布林值 hasField(Object object, String fieldName) 拋出例外
- 此語句檢查物件「object」是否聲明了名為「fieldName」的欄位。
-
- 參數:
目的待檢查對象欄位名– 要檢查的欄位名稱- 傳回值:
- 如果聲明為真,則為真
- 例外:
例外
取得所有字段
public static java.util.TreeSet 取得所有字段(對象對象)拋出異常
-
- 參數:
目的–- 傳回值:
- 例外:
例外
取得短類名
public static String 取得短類名(對象對象)
- 此函數從物件中檢索非限定類別名稱。
-
- 參數:
目的–- 傳回值:
取得短類名
public static String 取得短類名(字串類別名)
- 這會從完全限定名稱中檢索類別名稱。
-
- 參數:
類別名–- 傳回值:
GETFieldName
public static String GETFieldName(字串方法名)
- 將欄位名稱從方法名稱變更為其他名稱。這必須符合 JavaBeans 的命名規範。
-
- 參數:
資料名稱–- 傳回值:
isClassExist
公共靜態布林值 isClassExist(字串類別名)
- 這會檢查完全限定名稱「className」是否為存在的類別名稱。
-
- 參數:
類別名–- 傳回值:
取得屬性描述符
public static PropertyDescriptor[] 取得屬性描述符(物件物件)拋出 IntrospectionException
- 這將傳回一個 PropertyDescriptor,其中包含“object”的物件資訊。
-
- 參數:
目的–- 傳回值:
- 例外:
java.beans.IntrospectionException
BeanUtil 原始碼
/**
* 一個方便使用 Java 反射 API 的實用類別。
*/
public class BeanUtil {
/** */
private static final String GET = “GET”;
/** */
private static final String SET = “SET”;
// ———————————————————-‘newInstance’
/**
* 根據字串「className」建立並傳回一個實例。
* @param className 完全限定類別名
* @return 完全限定類別名稱的新實例
* @throws Exception
*/
public static Object newInstance(String className) throws Exception {
嘗試 {
return Class.forName(className).newInstance();
} catch (NoClassDefFoundError e) {
System.err.println(“NoClassDefFoundError:” + className);
三個 e;;
}
}
/**
* 根據字串「className」建立並傳回一個實例。
* @param className 完全限定類別名
* @param argObj 建構子參數
* @return 完全限定類別名稱的新實例
* @throws Exception
*/
public static Object newInstance(String className, Object[] argObj)
拋出例外 {
Class[] argClass = new Class[argObj.length];
for (int i = 0; i < argObj.length; i++) {
argClass[i] = argObj[i].getClass();
}
建構子 c = Class.forName(className).getConstructor(argClass);
返回 c.newInstance(argObj);
}
/**
* 建立並傳回「clazz」類別的一個實例。
* @param clazz 類
* @return Sunazz 的新實例
* @throws Exception
*/
public static Object newInstance(Class clazz) throws Exception {
返回 clazz.newInstance();
}
/**
* 建立並傳回「clazz」類別的一個實例。
* @param clazz 類
* @param argObj 建構子參數
* @return Sunazz 的新實例
* @throws Exception
*/
public static Object newInstance(Class clazz, Object[] argObj)
拋出例外 {
Class[] argClass = new Class[argObj.length];
for (int i = 0; i < argObj.length; i++) {
argClass[i] = argObj[i].getClass();
}
建構子 c = clazz.getConstructor(argClass);
返回 c.newInstance(argObj);
}
// - - - - - - - - - - -“方法”
/**
* 物件「invokeObject」的欄位「fieldName」的setter方法
* 呼叫並儲存值「value」。
* <br>
* 如果沒有 setter 方法,則直接將值設定到欄位中。
但是,在這種情況下,相關屬性的存取修飾符必須是 public。
* @param invokeObject 要呼叫的物件。
* @param fieldName 要執行操作的物件的屬性名稱。
* @param value 要設定的值
* @throws Exception 將發生以下異常:
* 當底層方法拋出例外狀況時,@throws InvocationTargetException
* @throws IllegalAccessException 此方法物件是 Java
* 如果實作了語言存取控制,且無法存取底層方法。
* 如果找不到具有指定名稱的方法,則拋出 NoSuchMethodException 例外。
*/
public static void setProperty(Object invokeObject, String fieldName,
物件值)拋出異常{
嘗試 {
方法 method = searchMethod(invokeObject, fieldName, SET);
Class[] paramClasses = method.getParameterTypes();
Object[] valueArray = null;
如果 (paramClasses[0].isInstance(value)) {
// 如果要設定的物件是參數類別的子類,則不會進行轉換。
valueArray = new Object[] { value };
別的 {
valueArray = new Object[] { convObject(value, paramClasses[0]
.getName()) };
}
method.invoke(invokeObject, valueArray);
} catch (NoSuchMethodException e) {
嘗試 {
// 如果沒有 setter 方法,則直接將其設為欄位值。
setField(invokeObject, fieldName, value);
} catch (NoSuchFieldException fe) {
String errorMes = “\nClass” + getShortClassName(invokeObject)
+ “是欄位”“ + 欄位名稱”“''\n”
“沒有可用的設定方法,而且。”
+ “字段”” + 字段名
「 + "」也不是公開的。;
throw new IllegalAccessException(errorMes);
}
}
}
/**
* 物件 invokeObject 的 fieldName 的 getter 方法
* 取得調用值。 <br>
* 如果沒有 getter 方法,則直接從欄位中檢索值。
但是,在這種情況下,相關屬性的存取修飾符必須是 public。
* @param invokeObject 要呼叫的物件。
* @param fieldName 要執行操作的物件的屬性名稱。
* @return getter 方法的回傳值
* @throws Exception 將發生以下異常:
* 當底層方法拋出例外狀況時,@throws InvocationTargetException
* @throws IllegalAccessException 此方法物件是 Java
* 如果實作了語言存取控制,且無法存取底層方法。
* 如果找不到具有指定名稱的字段,則拋出 NoSuchFieldException 例外。
*/
public static Object getProperty(Object invokeObject, String fieldName)
拋出例外 {
嘗試 {
方法 method = searchMethod(invokeObject, fieldName, GET);
返回 method.invoke(invokeObject, null);
} catch (NoSuchMethodException e) {
返回 getField(invokeObject, fieldName);
}
}
/**
* 執行物件“invokeObject”的“callMethod”方法。
* 如果有傳回值,則可以將其作為物件取得。
* @param invokeObject 要呼叫的物件。
* @param callMethod 要執行的方法的名稱
* @param argObjects 如果有參數,請將它們作為物件陣列傳遞。
* 如果沒有提供參數,則傳遞 null 值。
* @return 執行「callMethod」的回傳值
* 當底層方法拋出例外狀況時,@throws InvocationTargetException
* @throws IllegalAccessException 此方法物件是 Java
* 如果實作了語言存取控制,且無法存取底層方法。
* 如果找不到具有指定名稱的方法,則拋出 NoSuchMethodException 例外。
*/
public static Object invoke(Object invokeObject, String callMethod,
Object[] argObjects) 拋出 InvocationTargetException,,
IllegalAccessException,NoSuchMethodException {
方法 method = findMethod(invokeObject, callMethod, argObjects);
返回 method.invoke(invokeObject, argObjects);
}
/**
* 尋找物件“invokeObject”的方法“callMethod”。
* @param invokeObject 要呼叫的物件。
* @param callMethod 要執行的物件的方法名稱
* @param argObjects 如果有參數,請將它們作為物件陣列傳遞。
* 如果沒有提供參數,則傳遞 null 值。
* @return 符合指定參數條件的方法物件。
* 如果找不到符合的方法,則拋出 NoSuchMethodException 例外。
或名稱是“ ” 或者 “ 「如果是
*/
public static Method findMethod(Object invokeObject, String callMethod,
Object[] argObjects) 拋出 NoSuchMethodException {
Class[] paramClasses = null;
Method[] methods = invokeObject.getClass().getMethods();
top: for (int i = 0; i < methods.length; i++) {
如果 (methods[i].getName().equals(callMethod)) {
如果 (argObjects == null)
&& methods[i].getParameterTypes().length == 0) {
返回 methods[i];;
}
如果 (argObjects == null) {
繼續;
}
paramClasses = methods[i].getParameterTypes();
if (paramClasses.length == argObjects.length) {
// 驗證所有參數清單和參數的類型。
for (int j = 0; j < paramClasses.length; j++) {
類別 paramClass = paramClasses[j];
Object argObj = argObjects[j];
// 如果參數類型為原始類型,則為參數對象
// 不是 null 而是一個原始值
// 或者,Number 的任何子類別都是可以接受的。
如果 (argObj == null) {
繼續;
}
如果 (paramClass.isPrimitive()
&& (argObj instanceof Number || argObj
.getClass().isPrimitive())) {
繼續;
}
如果 (!paramClass.isInstance(argObj)) {
// 如果類型之間不存在隱式轉換相容性,則繼續下一個方法。
返回頂部;;
}
}
返回 methods[i];;
}
}
}
字串 paramLength = (paramClasses != null) ? 整數
.toString(paramClasses.length) : “”;
String errorMes = getShortClassName(invokeObject) + "方法"“
+ callMethod + “はありません。” + “[ paramClasses.length ] = ”
+ paramLength + “,[ argObjects.length ] = ” + argObjects.length
+“”;;
throw new NoSuchMethodException(errorMes);
}
// - - - - - - - - - - - “場地”
/**
* 設定要執行的物件「invokeObject」的欄位名稱「fieldName」的值。
* 儲存該值。
* @param invokeObject 要呼叫的物件。
* @param fieldName 要執行操作的物件的欄位名稱。
* @param value 要設定的值
* @throws IllegalAccessException 指定的物件是基於
* 一個欄位(或其子類別或實作)
* 如果它不是聲明了*的類別或介面的實例
* 或如果解包轉換失敗
* 如果找不到具有指定名稱的字段,則拋出 NoSuchFieldException 例外。
*/
public static void setField(Object invokeObject, String fieldName,
物件值) 拋出 IllegalAccessException、NoSuchFieldException {
字段 field = searchField(invokeObject, fieldName);
String className = field.getType().getName();
物件 convObj = null;
如果 (field.getType().isInstance(value)) {
convObj = 值;;
別的 {
convObj = convObject(value, className);
}
field.set(invokeObject, convObj);
}
/**
* 要執行「invokeObject」操作的物件中欄位名稱「fieldName」的值
* 將其取回。
* @param invokeObject 要呼叫的物件。
* @param fieldName 要執行操作的物件的欄位名稱。
* @return 回傳值
* @throws IllegalAccessException 指定的物件是基於
* 一個欄位(或其子類別或實作)
* 如果它不是聲明了*的類別或介面的實例
* 或如果解包轉換失敗
* 如果找不到具有指定名稱的字段,則拋出 NoSuchFieldException 例外。
*/
public static Object getField(Object invokeObject, String fieldName)
拋出 IllegalAccessException、NoSuchFieldException {
字段 field = searchField(invokeObject, fieldName);
返回 field.get(invokeObject);
}
/**
* 物件“object”是否聲明了欄位名稱“fieldName”
我會核實。
* @param object 要檢查的對象
* @param fieldName 要檢查的欄位名稱
* 如果聲明了 @return,則為真
* @throws Exception
*/
public static boolean hasField(Object object, String fieldName)
拋出例外 {
PropertyDescriptor[] props = getPropertyDescriptors(object);
for (int i = 0; i < props.length; i++) {
String _fieldName = props[i].getName();
如果 (fieldName.equals(_fieldName)) {
傳回 true;;
}
}
返回 false;;
}
/**
*
* @param 對象
* @返回
* @throws Exception
*/
public static TreeSet getAllFields(Object object) throws Exception {
TreeSet fieldSet = new TreeSet();
// 從方法中取得屬性名稱
PropertyDescriptor[] props = getPropertyDescriptors(object);
for (int i = 0; i < props.length; i++) {
String fieldName = props[i].getName();
fieldSet.add(fieldName);
}
// 從欄位取得屬性名稱
Field[] fields = object.getClass().getFields();
for (int i = 0; i < fields.length; i++) {
String fieldName = fields[i].getName();
如果 (!fieldSet.contains(fieldName)) {
fieldSet.add(fieldName);
}
}
返回 fieldSet;;
}
/**
*
* @param invokeObject 要呼叫的物件。
* @param fieldName 要執行操作的物件的欄位名稱。
* @return 符合指定參數條件的 Fielded 物件。
* 如果找不到具有指定名稱的字段,則拋出 NoSuchFieldException 例外。
*/
private static Field searchField(Object invokeObject, String fieldName)
拋出 NoSuchFieldException {
嘗試 {
返回 invokeObject.getClass().getField(fieldName);
} catch (NoSuchFieldException e) {
// 此作用域是從表格列名中檢索的
fieldName = checkFieldName(fieldName);
Field[] fields = invokeObject.getClass().getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equalsIgnoreCase(fieldName)) {
返回 fields[i];
}
}
拋出新的 NoSuchFieldException(fieldName);
}
}
// - - - - - - - - - - - “ 其他的 ”
/**
* 從物件中檢索非限定類別名稱。
* @param 對象
* @返回
*/
public static String getShortClassName(Object object) {
如果 (物件 == null) {
返回“null”;;
}
String name = object.getClass().getName();
返回 getShortClassName(name);;
}
/**
* 從完全限定名稱中檢索類別名稱。
* @param className
* @返回
*/
public static String getShortClassName(String className) {
int index = className.lastIndexOf(“.”);
return className.substring(index + 1);
}
/**
* 將欄位名稱從方法名稱變更為其他名稱。這符合 JavaBeans 的命名規範。
* 這是必填項。
* @param knowledgeName
* @返回
*/
public static String getFieldName(String methodName) {
字串 fieldName = null;
如果 (方法名稱以「is」開頭) {
fieldName = methodName.substring(2);
別的 {
fieldName = methodName.substring(3);
}
fieldName = convString(fieldName, 0, “L”);
返回字段名;;
}
/**
* 這會檢查完全限定名稱「className」是否為存在的類別名稱。
* @param className
* @返回
*/
public static boolean isClassExist(String className) {
嘗試 {
類別名稱.forName(className);
傳回 true;;
} catch (Exception e) {
返回 false;;
}
}
private final static Map beanInfoCache = new HashMap();
/**
* 傳回一個 PropertyDescriptor,其中包含「object」的物件資訊。
* @param 對象
* @返回
* @throws IntrospectionException
*/
public static PropertyDescriptor[] getPropertyDescriptors(Object object)
拋出 IntrospectionException {
BeanInfo beanInfo = (BeanInfo) beanInfoCache.get(object.getClass());
如果 (beanInfo == null) {
beanInfo = Introspector.getBeanInfo(object.getClass());
beanInfoCache.put(object.getClass(), beanInfo);
}
// BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
返回 beanInfo.getPropertyDescriptors();
}
// ————————————————————————–
// ———————————————『以下為私有方法’
// ————————————————————————–
/**
* 根據 PropertyDescriptor 搜尋參數 fieldName 的存取器方法。
* @param invokeObject 要呼叫的物件。
* @param fieldName 欄位名
* @param type 取得方法 ⇒ GET 取得方法 ⇒ SET
* @return 符合指定參數條件的方法物件。
* 如果找不到符合的方法,則拋出 NoSuchMethodException 例外。
或名稱是“ ” 或者 “ ”
* 如果是
* @throws IntrospectionException
*/
private static Method searchMethod(Object invokeObject, String fieldName,
字串型別)拋出 NoSuchMethodException、IntrospectionException {
方法函數 = null;
fieldName = checkFieldName(fieldName);
PropertyDescriptor[] props = getPropertyDescriptors(invokeObject);
for (int i = 0; i < props.length; i++) {
String name = props[i].getName();
如果 (!name.equalsIgnoreCase(fieldName)) {
繼續;
}
如果 (type.equals(GET)) {
method = props[i].getReadMethod();
別的 {
method = props[i].getWriteMethod();
}
如果 (method == null) {
繼續;
}
返回方法;;
}
// 如果該方法不存在。
throw new NoSuchMethodException("該類別沒有方法。")“
+ “(不區分大小寫):” + type.toLowerCase()
+ convString(fieldName, 0, “U”) + “()”);
}
/**
* 檢查參數 fieldName 是否為列名,如果是列名,則傳回 true
我會把它轉換回去。
*
* 郵件地址 ⇒ 郵件地址 ↓ 郵件地址 = 郵件地址
* @param fieldName 欄位名稱或列名
* @return 字段名
*/
private static String checkFieldName(String fieldName) {
int index = fieldName.indexOf(“_”);
while (true) {
如果 (index == -1) {
返回字段名;;
}
StringBuffer convcloumn = new StringBuffer(fieldName);
convcloum.deleteCharAt(index);
fieldName = convcloumn.toString();
index = fieldName.indexOf(“_”);
}
}
/**
* 將要轉換的物件轉換為 convClassName 指定的類型。
*
* @param object 要轉換的對象
* @param convClassName 要轉換成的類型的類別字串。
* @return 轉換後的對象
*/
private static Object convObject(Object object, String convClassName) {
如果 (物件 == null) {
// 如果轉換為原始類型後傳回 null,則會導致錯誤。
// 將其環繞 0。
如果 (convClassName.equals(“int”)) {
傳回新的整數(0);;
} else if (convClassName.equals(“long”)) {
返回新的 Long(0);;
別的 {
返回空值;;
}
}
如果 (object.getClass().getName().equals(convClassName)) {
返回對象;;
}
// —————————————-『 object instanceof String 』
if (object instanceof String) {
如果 (convClassName.equals(“java.lang.String”)) {
返回對象;;
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
String str = (String) object;
如果 (isExist(str)) {
// 除非先將其轉換為 BigDecimal 類型,否則將無法正常運作。
// 1000.00000
BigDecimal big = new BigDecimal(str);
返回新的 Long(big.longValue());
別的 {
// 如果 str 是 shell 字面量,則初始值為「0」。
返回新的 Long(0);;
}
} else if (convClassName.equals(“java.sql.Date”)) {
返回 toSqlDate((String) 物件);
} else if (convClassName.equals(“java.sql.Timestamp”)) {
Date date = toSqlDate((String) object);
返回新的時間戳(date.getTime());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
// 如果 str 是 shell 字面量,則初始值為「0」。
String str = (String) object;
如果 (isExist(str)) {
BigDecimal big = new BigDecimal(str);
返回新的 Integer(big.intValue());
別的 {
傳回新的整數(0);;
}
} else if (convClassName.equals(“boolean”)) {
return Boolean.valueOf(object.toString());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
String temp = ((String) object).trim();
// temp.length() == 0の場合0ではなくnullにするのが無難。
if (temp.length() == 0) {
返回空值;;
別的 {
返回新的 BigDecimal(temp);;
}
}
throwNoSupprt(object, convClassName);
}
// ———————————『 object instanceof java.sql.Date 』
else if (object instanceof java.sql.Date) {
如果 (convClassName.equals(“java.lang.String”)) {
返回 toStringDate((java.sql.Date) 物件, “yyyy/MM/dd”);
} else if (convClassName.equals(“java.sql.Date”)) {
返回對象;;
} else if (convClassName.equals(“java.sql.Timestamp”)) {
傳回新的 Timestamp(((Date) 物件).getTime());
}
throwNoSupprt(object, convClassName);
}
// ————————————-『 object instanceof Timestamp 』
else if (object instanceof Timestamp) {
long time = ((Timestamp) object).getTime();
如果 (convClassName.equals(“java.lang.String”)) {
返回 toStringDate(time, “yyyy/MM/dd HH:mm:ss”);
} else if (convClassName.equals(“java.sql.Date”)) {
返回新的 java.sql.Date(time);;
} else if (convClassName.equals(“java.sql.Timestamp”)) {
返回對象;;
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof Integer 』
else if (object instanceof Integer) {
如果 (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
返回對象;;
} else if (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
傳回一個新的 Long 物件(((Integer)物件).longValue();;
} else if (convClassName.equals(“java.math.BigDecimal”)) {
回傳一個新的 BigDecimal(((Integer) object).intValue());
}
throwNoSupprt(object, convClassName);
}
// ——————————————『 object instanceof Long 』
else if (object instanceof Long) {
如果 (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
返回對象;;
} else if (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回一個新的 Integer(((Long) object).intValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
傳回一個新的 BigDecimal(((Long) 物件).longValue());
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof Double 』
else if (object instanceof Double) {
如果 (convClassName.equals(“java.lang.String”)) {
// 列號(8,0)
// windows oracle > BigDecimal
// UNIX oracle > 雙精度浮點數
BigDecimal big = new BigDecimal(((Double) object).doubleValue());
int scale = big.scale();
如果(縮放比例 == 0){
return big.toString();
別的 {
// 若需要進行舍入,則不支援舍入。
throwNoSupprt(object, convClassName);
}
}
如果 (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回新的 Integer(((Double) object).intValue());
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
傳回一個新的 Long(((Double) 物件).longValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
回傳一個新的 BigDecimal(((Double) 物件).doubleValue());
}
throwNoSupprt(object, convClassName);
}
// ————————————『 object instanceof BigDecimal 』
else if (object instanceof BigDecimal) {
如果 (convClassName.equals(“java.lang.String”)) {
return object.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
傳回一個新的 Long(((BigDecimal) 物件).longValue());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回一個新的 Integer(((BigDecimal) object).intValue());
}
throwNoSupprt(object, convClassName);
}
// —————————————-『 object instanceof byte[] 』
else if (object instanceof byte[]) {
如果 (convClassName.equals(“java.sql.Blob”)) {
返回對象;;
}
throwNoSupprt(object, convClassName);
}
// ————————————————『物件為布林值』
else if (object instanceof Boolean) {
如果 (convClassName.equals(“boolean”)) {
返回對象;;
}
throwNoSupprt(object, convClassName);
}
// ———————————————-‘物件是一個布林數組’
else if (object instanceof boolean[]) {
如果 (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);
返回空值;;
}
/**
* 如果不支援轉換,則拋出異常。
*
* @param object 要轉換的對象
* @param convClassName 要轉換為的型別
*/
private static void throwNoSupprt(Object object, String convClassName) {
String className = (object != null) ? object.getClass().getName()
: “無效的”;
String errorMess = "\n此物件的型別轉換尚不支援。\n"“
+”[物件]=”+物件+“,[物件類型]=”+類別名
+ “,[ convertClass ] = ” + convClassName + “”;
throw new UnsupportedOperationException(errorMess);
}
/**
* 將字串 [str] 中位置 [index] 處的字元轉換為大寫或小寫。
* <p>
* @param str 要評估的字串
* @param index 指定位置
* @param toCase 轉換為大寫 ⇒ U | u 轉換為小寫 ⇒ L | l
* @return 轉換後的字串
*/
private static String convString(String str, int index, String toCase) {
if (str == null || str.trim().length() == 0) {
返回字串;;
別的 {
String temp = str.substring(index, index + 1);
if (toCase.equalsIgnoreCase(“u”)) {
temp = temp.toUpperCase();
別的 {
temp = temp.toLowerCase();
}
StringBuffer tempBuffer = new StringBuffer(str);
tempBuffer.replace(index, index + 1, temp);
return tempBuffer.toString();
}
}
/**
* 這會驗證 [value] 是否為有效值。
*
* @param value 要評估的字串
* @return [true]: 如果不為空且不為空
*/
private static boolean isExist(String value) {
if (value != null && value.length() != 0) {
傳回 true;;
}
返回 false;;
}
/**
* 指定格式的 java.util.Date 類別或其子類
* 轉換為字串。
* @param date 要轉換的 javautil.Date 類
* @param pattern 指定格式
* 傳回格式化的日期字串
*/
private static String toStringDate(Date date, String pattern) {
SimpleDateFormat sdFormat = new SimpleDateFormat(pattern);
返回 sdFormat.format(date);
}
private static java.sql.Date toSqlDate(String strDate) {
Calendar cal = toCalendar(strDate);
返回 toSqlDate(cal);
}
private static java.sql.Date toSqlDate(Calendar cal) {
long l = cal.getTime().getTime();
返回新的 java.sql.Date(l);;
}
/**
* 將長時間值轉換為指定格式的字串。
* @param time 一個長整數值,表示目前時間(以毫秒為單位)。
* @param pattern 指定格式
* 傳回格式化的日期字串
*/
private static String toStringDate(long time, String pattern) {
返回 toStringDate(new Date(time), pattern);
}
/**
* String ⇒ java.sql.Date
*
將以下日期字串轉換為 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
* @返回
*/
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();
switch (len) {
案例10:
休息;
案例 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);
休息;
案例 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);
休息;
案例 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);
休息;
預設:
拋出新的 IllegalStateException(
“此字串無法轉換為日期字串:”
+ strDate);
}
返回 cal;;
}
/**
* 任何日期字串都可以採用「yyyy/MM/dd」或「yyyy/MM/dd HH:mm:ss」格式。
* 嘗試轉換為該格式。
* 例如:03/1/3 ⇒ 2003/01/03
* @param strDate
* @返回
*/
private static String format(String strDate) {
strDate = strDate.trim();
字串 yyyy = null;
字串 MM = null;
字串 dd = null;
字串 HH = null;
字串 mm = null;
字串 ss = null;
字串 SSS = null;
// 如果沒有“-”或“/”
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);
返回 yyyy + “/” + MM + “/” + dd;
別的 {
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);
返回 yyyy + “/” + MM + “/” + dd + ” ” + HH + “:” + mm + “:”
+ ss;;
}
}
StringTokenizer token = new StringTokenizer(strDate, “_/-:. “);
StringBuffer result = new StringBuffer();
for (int i = 0; token.hasMoreTokens(); i++) {
String temp = token.nextToken();
開關 (i) {
案例 0: 年部分
yyyy = fillString(strDate, temp, “f”, “20”, 4);
result.append(yyyy);
休息;
案例 1:// 月部分
MM = fillString(strDate, temp, “f”, “0”, 2);
result.append("/" + MM);
休息;
案例 2:// 一天中的部分時間
dd = fillString(strDate, temp, “f”, “0”, 2);
result.append("/" + dd);
休息;
案例 3:時間部分
HH = fillString(strDate, temp, “f”, “0”, 2);
result.append(" " + HH);
休息;
案例 4:// 部分
mm = fillString(strDate, temp, “f”, “0”, 2);
result.append(":" + mm);
休息;
案例 5:// 關於秒的部分
ss = fillString(strDate, temp, “f”, “0”, 2);
result.append(":" + ss);
休息;
案例 6:// 毫秒部分
SSS = fillString(strDate, temp, “b”, “0”, 3);
result.append("." + SSS);
休息;
}
}
return result.toString();
}
private static String fillString(String strDate, String str,
String position, String addStr, int len) {
if (str.length() > len) {
String mes = strDate + "此字串無法轉換為日期字串";
拋出新的 IllegalStateException(mes);
}
return fillString(str, position, addStr, len);
}
/**
將要新增至字串 [str] 的字串設為位置 [position],然後設定為 [len]。
* 插入直至充滿。
* <p>
* 範例:String ss = StringUtil.fillString(“aaa”,”b”,”0″,7); ss ⇒ “aaa0000”
*
*注意:fillString() 會插入字串直到達到 len,而 addString() 會插入長度等於 len 的字串。
*
* @param str 目標字串
* @param position 插入位置在 ⇒ F/f 之前 插入位置在 ⇒ B/b 之後
* @param addStr 要插入的字串
* @param len 要新增的數字位數
* @return 轉換後的字串。如果 [str] 為空或空字面量,則 [addStr] 將轉換為 [len]。
* 傳回插入操作的結果,直到滿足條件為止。
*/
private static String fillString(String str, String position,
String addStr, int len) {
StringBuffer tempBuffer = null;
如果 (!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()) {
如果 (position.equalsIgnoreCase(“f”)) {
tempBuffer.insert(0, addStr);
別的 {
tempBuffer.append(addStr);
}
}
return tempBuffer.toString();
}
返回字串;;
}
}
