Java 反射變簡單
爪哇的反射引入一個實用程式類,可讓您輕鬆使用 API。
什麼是反射?
反射API牙齒,”java.lang.reflect” 包含在包裝中,
這是一個從 Java 類別檢索欄位和方法等資訊的 API。
主要用到以下幾個類別。
- java.lang.Class
- java.lang.reflect.建構函數
- java.lang.reflect.Method
- java.lang.reflect.Field
反射透過使用,您可以建立類別或呼叫方法,而無需直接對其進行編碼。
您可以從字串建立類別實例或執行方法。
透過將類別名稱和方法名稱的定義寫入外部檔案(例如 XML)中,您可以動態地使應用程式適應執行時間環境的變化。
它也是建立高度靈活的應用程式的非常有效的 API。
反思的目的
反射使用者不常直接使用,
它廣泛應用於 Struts 等 Web 應用程式和 O/R 映射等框架中。
例如,當自動將 Web 畫面輸入資料設定為 JavaBeans 屬性時,
它在發出基於 JavaBeans 屬性自動更新的 SQL 時使用。
此外,還提供諸如在應用程式啟動時動態載入和註冊擴充功能的插件等功能。反射使用 可以輕鬆實現這一點。
運行範例
請運行範例並體驗類似框架的程式設計。
這裡我們使用下面的類別反射示範該實用程式的簡單用法。
主程式.java....要執行的類別
BeanUtil.java...反射實用程式類
自由軟體.java……用作代表自由軟體的類別中的反射。
●正常執行時
FreeSoft freeSoft = new FreeSoft();
freeSoft.setName(“聊天和信使聊天和信使!!”);
freeSoft.showName();
freeSoft.showPrice(0);
●使用反射執行時
//建立FreeSoft類別的實例
物件 invokeObject = BeanUtil.newInstance(“自由軟體”);
//設定名稱欄位中的值。
BeanUtil.setProperty(invokeObject, “姓名” , “聊天和信使 聊天和信使!!”);
// 執行 FreeSoft 的 showName() 方法。
BeanUtil.invoke(invokeObject, “演出名稱”, 無效的);
// 執行 FreeSoft 的 showPrice() 方法。
// 如果方法有參數,則它們必須作為物件類型陣列傳遞。
BeanUtil.invoke(invokeObject, “顯示價格”,new Object[]{new Integer(0)});
●執行結果
無論是正常情況還是使用反射,執行結果都是一樣的。
軟體名稱:Chat&Messenger 聊天和信差! !
價格:0日圓
>>> 使用反射時
軟體名稱:Chat&Messenger 聊天和信差! !
價格:0日圓
BeanUtil 方法詳細信息
新實例
公共靜態物件 新實例(字串類別名)拋出異常
- 從字串“className”產生並傳回一個實例。
-
- 參數:
班級名稱
– 完全限定的類別名- 傳回值:
- 完全限定類別名稱的新實例
- 例外:
例外
新實例
公共靜態物件 新實例(String className, Object[] argObj) 拋出異常
- 從字串“className”產生並傳回一個實例。
-
- 參數:
班級名稱
– 完全限定的類別名argObj
– 建構函式參數- 傳回值:
- 完全限定類別名稱的新實例
- 例外:
例外
新實例
公共靜態物件 新實例(類 clazz)拋出異常
- 產生並傳回類別“clazz”的實例。
-
- 參數:
克拉茲
- 班級- 傳回值:
- clazz 的新實例
- 例外:
例外
新實例
公共靜態物件 新實例(類別 clazz,Object[] argObj)拋出異常
- 產生並傳回類別“clazz”的實例。
-
- 參數:
克拉茲
- 班級argObj
– 建構函式參數- 傳回值:
- clazz 的新實例
- 例外:
例外
設定屬性
公共靜態無效 設定屬性(物件invokeObject,字串欄位名稱,物件值)拋出異常
- 呼叫物件“invokeObject”的欄位“fieldName”的setter方法並儲存值“value”。
如果沒有setter方法,值將直接設定到欄位中。但是,在這種情況下,目標屬性的存取修飾符必須是 public。
-
- 參數:
呼叫對象
– 要執行的對象欄位名
– 要執行的物件的屬性名稱價值
– 要設定的值- 例外:
例外
– 出現以下異常。呼叫目標異常
– 如果底層方法拋出異常非法存取異常
– 這個Method物件是Java
當實現語言存取控製而無法存取底層方法時沒有這樣的方法異常
– 如果找不到指定名稱的方法
取得屬性
公共靜態物件 取得屬性(Object invokeObject, String fieldName) 拋出例外
- 呼叫物件invokeObject的欄位fieldName的getter方法取得值。
如果沒有 getter 方法,將直接從欄位中檢索值。但是,在這種情況下,目標屬性的存取修飾符必須是 public。 -
- 參數:
呼叫對象
– 要執行的對象欄位名
– 要執行的物件的屬性名稱- 傳回值:
- Getter方法傳回值
- 例外:
例外
– 出現以下異常。呼叫目標異常
– 如果底層方法拋出異常非法存取異常
– 這個Method物件是Java
當實現語言存取控製而無法存取底層方法時沒有這樣的欄位異常
– 如果未找到指定名稱的字段
呼叫
公共靜態物件 呼叫(Object invokeObject、String callMethod、Object[] argObjects) 拋出 InvokingTargetException、IllegalAccessException、NoSuchMethodException
- 執行物件“invokeObject”的方法“callMethod”。
如果有傳回值,則可以以 Object 的形式取得。 -
- 參數:
呼叫對象
– 要執行的對象呼叫方法
– 要執行的方法名稱arg對象
– 如果有參數,則將它們作為物件陣列傳遞。如果沒有參數,則傳遞 null。- 傳回值:
- 執行“callMethod”的回傳值
- 例外:
呼叫目標異常
– 如果底層方法拋出異常非法存取異常
– 這個Method物件是Java
當實現語言存取控製而無法存取底層方法時沒有這樣的方法異常
– 如果找不到指定名稱的方法
尋找方法
公共靜態方法 尋找方法(Object invokeObject, String callMethod, Object[] argObjects) 拋出 NoSuchMethodException
- 搜尋物件“invokeObject”的方法“callMethod”。
-
- 參數:
呼叫對象
– 要執行的對象呼叫方法
– 要執行的物件的方法名稱arg對象
– 如果有參數,則將它們作為物件陣列傳遞。如果沒有參數,則傳遞 null。- 傳回值:
- 與指定參數條件相符的 Method 對象
- 例外:
沒有這樣的方法異常
– 如果沒有找到符合的方法,或名稱是“”或“”
設定字段
公共靜態無效 設定字段(物件 invokeObject、字串欄位名稱、物件值)拋出 IllegalAccessException、NoSuchFieldException
- 將值「value」儲存在要執行的物件「invokeObject」的欄位名稱「fieldName」中。
-
- 參數:
呼叫對象
– 要執行的對象欄位名
– 待執行物件的欄位名價值
– 要設定的值- 例外:
非法存取異常
– 指定物件所基於的欄位(或其子類別或實作者)
不是它聲明的類別或介面的實例,或展開轉換失敗沒有這樣的欄位異常
– 如果未找到指定名稱的字段
取得字段
公共靜態物件 取得字段(Object invokeObject, String fieldName) 拋出 IllegalAccessException, NoSuchFieldException
- 取得要執行的物件「invokeObject」的欄位名稱「fieldName」的值。
-
- 參數:
呼叫對象
– 要執行的對象欄位名
– 待執行物件的欄位名- 傳回值:
- 傳回值
- 例外:
非法存取異常
– 指定物件所基於的欄位(或其子類別或實作者)
不是它聲明的類別或介面的實例,或展開轉換失敗沒有這樣的欄位異常
– 如果未找到指定名稱的字段
有字段
公共靜態布林值 有字段(對象對象,字串欄位名稱)拋出異常
- 檢查物件“object”是否聲明欄位名稱“fieldName”。
-
- 參數:
目的
– 待檢查對象欄位名
– 要檢查的欄位名稱- 傳回值:
- true 如果聲明
- 例外:
例外
取得所有字段
公共靜態java.util.TreeSet 取得所有字段(對象對象)拋出異常
-
- 參數:
目的
–- 傳回值:
- 例外:
例外
取得短類名
公共靜態字串 取得短類名(對象對象)
- 從物件取得非限定類別名稱。
-
- 參數:
目的
–- 傳回值:
取得短類名
公共靜態字串 取得短類名(字串類別名)
- 從完全限定名稱中取得類別名稱。
-
- 參數:
班級名稱
–- 傳回值:
取得欄位名
公共靜態字串 取得欄位名(字串方法名稱)
- 更改方法名稱中的欄位名稱。必須符合 JavaBeans 約定。
-
- 參數:
方法名
–- 傳回值:
類別是否存在
公共靜態布林值 類別是否存在(字串類別名)
- 驗證完全限定名稱「className」是否是現有的類別名稱。
-
- 參數:
班級名稱
–- 傳回值:
取得屬性描述符
公共靜態PropertyDescriptor[] 取得屬性描述符(Object 物件) 拋出 IntrospectionException
- 傳回一個 PropertyDescriptor,其中保存「object」的物件資訊。
-
- 參數:
目的
–- 傳回值:
- 例外:
java.beans.IntrospectionException
BeanUtil原始碼
/**
* 實用類,可以讓你輕鬆使用Java的反射API
*/
公共類別 BeanUtil {
/** */
私有靜態最終字串 GET = “GET”;
/** */
私有靜態最終字符串SET =“SET”;
// ————————————————————-‘newInstance’
/**
* 從字串「className」產生並傳回一個實例。
* @param className 完全限定類別名
* @return 完全限定類別名稱的新實例
* @拋出例外
*/
公共靜態物件 newInstance(String className) 拋出異常 {
嘗試 {
return Class.forName(className).newInstance();
} catch (NoClassDefFoundError e) {
System.err.println(“NoClassDefFoundError:” + 類別名稱);
扔 e;
}
}
/**
* 從字串「className」產生並傳回一個實例。
* @param className 完全限定類別名
* @param argObj 建構子參數
* @return 完全限定類別名稱的新實例
* @拋出例外
*/
公共靜態物件 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 clazz的新實例
* @拋出例外
*/
公共靜態物件 newInstance(Class clazz) 拋出異常 {
返回 clazz.newInstance();
}
/**
* 建立並傳回類別「clazz」的實例。
* @param clazz 類
* @param argObj 建構子參數
* @return clazz的新實例
* @拋出例外
*/
公共靜態物件 newInstance(類別 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 InvokingTargetException
* @throws IllegalAccessException 如果此 Method 物件是 Java
* 當實作語言存取控製而無法存取底層方法時
* 如果找不到指定名稱的方法,則@拋出NoSuchMethodException
*/
公共靜態無效setProperty(物件invokeObject,字串欄位名稱,
物件值)拋出異常 {
嘗試 {
方法 method = searchMethod(invokeObject, fieldName, SET);
Class[] paramClasses = method.getParameterTypes();
物件[] valueArray = null;
if (paramClasses[0].isInstance(value)) {
//如果要設定的物件是參數類別的子類,則不進行轉換。
valueArray = new Object[] { 值 };
} 別的 {
valueArray = new Object[] { convObject(值, paramClasses[0]
.getName()) };
}
方法.invoke(invokeObject, valueArray);
} catch (NoSuchMethodException e) {
嘗試 {
// 如果沒有setter方法,則直接設定到欄位。
setField(invokeObject, 欄位名稱, 值);
} catch (NoSuchFieldException fe) {
字串 errorMes = “\nClass” + getShortClassName(invokeObject)
+“是”+“對於字段“”+字段名稱+“”\n”
+“沒有可訪問的 setter 方法,並且。”
+ “字段”” + 字段名稱
+“”也不公開。 ” + “”;
拋出新的 IllegalAccessException(errorMes);
}
}
}
/**
* 物件invokeObject的欄位fieldName的Getter方法
* 取得調用值。 <br>
* 如果沒有getter方法,則直接從欄位取得值。
* 但是,在這種情況下,目標屬性的存取修飾符必須是 public。
* @param invokeObject 要執行的對象
* @param fieldName 要執行的物件的屬性名稱
* @return getter方法的回傳值
* @throws Exception 發生以下異常。
* 如果底層方法拋出異常,則@throws InvokingTargetException
* @throws IllegalAccessException 如果此 Method 物件是 Java
* 當實作語言存取控製而無法存取底層方法時
* 如果未找到具有指定名稱的字段,則@拋出NoSuchFieldException
*/
公共靜態物件 getProperty(物件 invokeObject,字串欄位名稱)
拋出例外{
嘗試 {
方法 method = searchMethod(invokeObject, fieldName, GET);
return method.invoke(invokeObject, null);
} catch (NoSuchMethodException e) {
返回 getField(invokeObject, fieldName);
}
}
/**
* 執行物件“invokeObject”的方法“callMethod”。
* 如果有回傳值,可以以Object類型取得。
* @param invokeObject 要執行的對象
* @param callMethod 要執行的方法名
* @param argObjects 如果有參數,則將其作為物件陣列傳遞。
* 如果沒有參數則傳遞 null。
* @return 執行「callMethod」的回傳值
* 如果底層方法拋出異常,則@throws InvokingTargetException
* @throws IllegalAccessException 如果此 Method 物件是 Java
* 當實作語言存取控製而無法存取底層方法時
* 如果找不到指定名稱的方法,則@拋出NoSuchMethodException
*/
公共靜態物件呼叫(物件invokeObject,字串callMethod,
Object[] argObjects) 拋出 InitationTargetException,
IllegalAccessException,NoSuchMethodException {
方法 method = findMethod(invokeObject, callMethod, argObjects);
return method.invoke(invokeObject, argObjects);
}
/**
* 搜尋物件「invokeObject」的方法「callMethod」。
* @param invokeObject 要執行的對象
* @param callMethod 要執行的物件的方法名稱
* @param argObjects 如果有參數,則將其作為物件陣列傳遞。
* 如果沒有參數則傳遞 null。
* @return 與指定參數條件匹配的方法對象
* @throws NoSuchMethodException 如果沒有找到匹配的方法,
* 或如果名稱是“ “ 或者 ” 「如果是
*/
公共靜態方法findMethod(物件invokeObject,字串callMethod,
Object[] argObjects) 拋出 NoSuchMethodException {
類別[] paramClasses = null;
Method[] 方法 = invokeObject.getClass().getMethods();
上: for (int i = 0; i <methods.length; i++) {
if (methods[i].getName().equals(callMethod)) {
if (argObjects == null
&& 方法[i].getParameterTypes().length == 0) {
返回方法[i];
}
if (argObjects == null) {
繼續;
}
paramClasses = 方法[i].getParameterTypes();
if (paramClasses.length == argObjects.length) {
// 驗證所有參數清單類型和實參類型
for (int j = 0; j < paramClasses.length; j++) {
類別 paramClass = paramClasses[j];
物件 argObj = argObjects[j];
// 如果參數類型是原始類型,則參數對象
// 不為 null 且是原始型別
//如果是Number的子類別就可以了。
if (argObj == null) {
繼續;
}
if (paramClass.isPrimitive()
&& (argObj 實例編號 || argObj
.getClass().isPrimitive())) {
繼續;
}
if (!paramClass.isInstance(argObj)) {
// 當型別不相容隱式轉換時,繼續執行下一個方法
繼續頂部;
}
}
返回方法[i];
}
}
}
字串 paramLength = (paramClasses != null) ? 整數
.toString(paramClasses.length) : “”;
字串 errorMes = getShortClassName(invokeObject) + “方法”
+ callMethod + “沒有。” + “[ paramClasses.length ] = ”
+ paramLength + “,[ argObjects.length ] = ” + argObjects.length
+ “”;
拋出新的NoSuchMethodException(errorMes);
}
// - - - - - - - - - - - “場地”
/**
* 要執行的物件「invokeObject」的欄位名稱「fieldName」的值
* 儲存“值”。
* @param invokeObject 要執行的對象
* @param fieldName 待執行物件的欄位名
* @param value 要設定的值
* @throws IllegalAccessException 如果指定的物件是
* 欄位(或其子類別或實作者)
* 如果不是類別或介面的實例,則聲明
* 或如果解包轉換失敗
* 如果未找到具有指定名稱的字段,則@拋出NoSuchFieldException
*/
公共靜態無效setField(物件invokeObject,字串欄位名稱,
物件值)拋出 IllegalAccessException、NoSuchFieldException {
字段 field = searchField(invokeObject, fieldName);
String className = field.getType().getName();
物件 convObj = null;
if (field.getType().isInstance(value)) {
convObj = 值;
} 別的 {
convObj = convObject(值, 類別名稱);
}
field.set(invokeObject, convObj);
}
/**
* 將執行物件「invokeObject」的欄位名稱「fieldName」的值設為
* 得到。
* @param invokeObject 要執行的對象
* @param fieldName 待執行物件的欄位名
* @return 回傳值
* @throws IllegalAccessException 如果指定的物件是
* 欄位(或其子類別或實作者)
* 如果不是類別或介面的實例,則聲明
* 或如果解包轉換失敗
* 如果未找到具有指定名稱的字段,則@拋出NoSuchFieldException
*/
公用靜態 Object getField(Object invokeObject, String fieldName)
拋出 IllegalAccessException, NoSuchFieldException {
字段 field = searchField(invokeObject, fieldName);
返回 field.get(invokeObject);
}
/**
* 檢查物件“object”是否宣告欄位名稱“fieldName”
* 確認。
* @param object 要檢查的對象
* @param fieldName 要檢查的欄位名稱
* @return true 如果聲明
* @拋出例外
*/
公共靜態布林hasField(物件對象,字串欄位名稱)
拋出例外{
PropertyDescriptor[] props = getPropertyDescriptors(object);
for (int i = 0; i < props.length; i++) {
String _fieldName = props[i].getName();
if (fieldName.equals(_fieldName)) {
返回真;
}
}
返回假;
}
/**
*
* @param對象
* @返回
* @拋出例外
*/
公共靜態TreeSet getAllFields(物件物件)拋出異常{
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();
if (!fieldSet.contains(fieldName)) {
fieldSet.add(fieldName);
}
}
返回字段集;
}
/**
*
* @param invokeObject 要執行的對象
* @param fieldName 待執行物件的欄位名
* @return 與指定參數條件相符的歸檔對象
* 如果未找到具有指定名稱的字段,則@拋出NoSuchFieldException
*/
私有靜態欄位 searchField(Object invokeObject, String fieldName)
拋出 NoSuchFieldException {
嘗試 {
返回invokeObject.getClass().getField(fieldName);
} catch (NoSuchFieldException e) {
// 這個作用域是從表格列名中取得的
欄位名稱 = checkFieldName(欄位名稱);
Field[] fields = invokeObject.getClass().getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equalsIgnoreCase(fieldName)) {
返回字段[i];
}
}
拋出新的NoSuchFieldException(欄位名稱);
}
}
// - - - - - - - - - - - “ 其他的 ”
/**
* 從物件中取得非限定類別名稱。
* @param對象
* @返回
*/
公用靜態字串 getShortClassName(物件物件){
如果(物件==空){
返回「空」;
}
字串名稱 = object.getClass().getName();
傳回 getShortClassName(名稱);
}
/**
* 從完全限定名稱中取得類別名稱。
* @param 類別名
* @返回
*/
公用靜態 String getShortClassName(String className) {
int index = className.lastIndexOf(“.”);
return className.substring(index + 1);
}
/**
* 變更方法名稱中的欄位名稱。符合 JavaBeans 約定
* 是需要的。
* @param 方法名
* @返回
*/
公用靜態 String getFieldName(String 方法名稱) {
字串字段名 = null;
if (methodName.startsWith(“is”)) {
字段名 = 方法名.substring(2);
} 別的 {
字段名 = 方法名.substring(3);
}
欄位名稱 = convString(欄位名稱, 0, “L”);
返回字段名;
}
/**
* 驗證完全限定名稱「className」是現有的類別名稱。
* @param 類別名
* @返回
*/
公用靜態布林 isClassExist(String className) {
嘗試 {
Class.forName(類別名稱);
返回真;
} catch (異常 e) {
返回假;
}
}
私有最終靜態Map beanInfoCache = new HashMap();
/**
* 回傳一個PropertyDescriptor,它保存「object」的物件資訊。
* @param對象
* @返回
* @拋出內省例外
*/
公共靜態PropertyDescriptor [] getPropertyDescriptors(物件物件)
拋出內省異常 {
BeanInfo beanInfo = (BeanInfo) beanInfoCache.get(object.getClass());
if (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 Getter 方法 ⇒ GET Getter 方法 ⇒ SET
* @return 與指定參數條件匹配的方法對象
* @throws NoSuchMethodException 如果沒有找到匹配的方法,
* 或如果名稱是“ “ 或者 ” 」
* 如果是
* @拋出內省例外
*/
私有靜態方法 searchMethod(Object invokeObject, String fieldName,
字串型別)拋出 NoSuchMethodException、IntrospectionException {
方法方法=空;
欄位名稱 = checkFieldName(欄位名稱);
PropertyDescriptor[] props = getPropertyDescriptors(invokeObject);
for (int i = 0; i < props.length; i++) {
字串名稱 = props[i].getName();
if (!name.equalsIgnoreCase(fieldName)) {
繼續;
}
if (type.equals(GET)) {
方法 = props[i].getReadMethod();
} 別的 {
方法 = props[i].getWriteMethod();
}
如果(方法==空){
繼續;
}
返回方法;
}
// 如果該方法不存在。
throw new NoSuchMethodException(“類別沒有方法。”
+ 「(不區分大小寫。):」 + type.toLowerCase()
+ convString(字段名稱, 0, “U”) + “()”);
}
/**
* 檢查參數fieldName是否為列名;如果是列名,
* 轉換回來。
*
* MAIL_ADDRESS ⇒ MAILADDRESS ↓ 郵件地址 = 郵件地址
* @param fieldName 欄位名稱或列名
* @return 字段名
*/
私人靜態字串 checkFieldName(String fieldName) {
int index = fieldName.indexOf(“_”);
而(真){
如果(索引==-1){
返回字段名;
}
StringBuffer convcloumn = new StringBuffer(fieldName);
convcloumn.deleteCharAt(索引);
欄位名稱 = convcloumn.toString();
index = fieldName.indexOf(“_”);
}
}
/**
* 將要轉換的物件object轉換為convClassName的類型。
*
* @param object 要轉換的對象
* @param convClassName 要轉換的類型的類別字串
* @return 轉換後的對象
*/
私有靜態物件 convObject(物件對象,字串 convClassName) {
如果(物件==空){
// 轉換為基本型別時傳回 null 會導致錯誤。
// 使其成為 0 的包裝器。
if (convClassName.equals(“int”)) {
返回新整數(0);
} else if (convClassName.equals(“long”)) {
返回新的長(0);
} 別的 {
返回空值;
}
}
if (object.getClass().getName().equals(convClassName)) {
返回對象;
}
// ——————————————-『字串的物件實例’
if (字串的物件實例) {
if (convClassName.equals(“java.lang.String”)) {
返回對象;
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
字串 str = (字串) 物件;
如果(isExist(str)){
// 如果不轉換一次BigDecimal就不好了
// 1000.00000
BigDecimal big = new BigDecimal(str);
返回新的 Long(big.longValue());
} 別的 {
// 如果 str 是 shell 文字,則將初始值設為“0”
返回新的長(0);
}
} else if (convClassName.equals(“java.sql.Date”)) {
返回 SqlDate((String) 物件);
} else if (convClassName.equals(“java.sql.Timestamp”)) {
日期日期 = toSqlDate((String) 物件);
返回新時間戳(date.getTime());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
// 如果 str 是 shell 文字,則將初始值設為“0”
字串 str = (字串) 物件;
如果(isExist(str)){
BigDecimal big = new BigDecimal(str);
傳回新的整數(big.intValue());
} 別的 {
返回新整數(0);
}
} else if (convClassName.equals(“boolean”)) {
return Boolean.valueOf(object.toString());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
字串暫存 = ((String) 物件).trim();
// 如果 temp.length() == 0,則可以安全地將其設為 null 而不是 0。
if (temp.length() == 0) {
返回空值;
} 別的 {
返回新的 BigDecimal(temp);
}
}
throwNoSupprt(物件, convClassName);
}
// ———————————“java.sql.Date 物件實例”
else if (java.sql.Date 物件實例) {
if (convClassName.equals(“java.lang.String”)) {
return toStringDate((java.sql.Date) 物件, “yyyy/MM/dd”);
} else if (convClassName.equals(“java.sql.Date”)) {
返回對象;
} else if (convClassName.equals(“java.sql.Timestamp”)) {
傳回新時間戳(((Date)物件).getTime());
}
throwNoSupprt(物件, convClassName);
}
// ———————————-‘時間戳的物件實例’
else if (時間戳物件實例) {
長時間 = ((時間戳) 物件).getTime();
if (convClassName.equals(“java.lang.String”)) {
return toStringDate(時間,“yyyy/MM/dd HH:mm:ss”);
} else if (convClassName.equals(“java.sql.Date”)) {
返回新的 java.sql.Date(時間);
} else if (convClassName.equals(“java.sql.Timestamp”)) {
返回對象;
}
throwNoSupprt(物件, convClassName);
}
// ——————————————-『Integer 的物件實例’
else if (物件實例整數) {
if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
返回對象;
} else if (convClassName.equals(“java.lang.String”)) {
返回物件.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
return new Long(((Integer) object).longValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
返回 new BigDecimal(((Integer) object).intValue());
}
throwNoSupprt(物件, convClassName);
}
// ——————————————『Long物件實例’
else if (物件實例長) {
if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
返回對象;
} else if (convClassName.equals(“java.lang.String”)) {
返回物件.toString();
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回新的 Integer(((Long) 物件).intValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
返回新的 BigDecimal(((Long) 物件).longValue());
}
throwNoSupprt(物件, convClassName);
}
// ——————————————-‘Double 物件實例’
else if (雙精確度物件實例) {
if (convClassName.equals(“java.lang.String”)) {
// 列號(8,0)
// windows oracle > BigDecimal
// UNIX oracle > 雙精度
BigDecimal big = new BigDecimal(((Double) 物件).doubleValue());
int 比例 = big.scale();
如果(比例== 0){
返回big.toString();
} 別的 {
// 如果需要捨入,則不支援。
throwNoSupprt(物件, convClassName);
}
}
if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回新的 Integer(((Double) 物件).intValue());
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
傳回 new Long(((Double) 物件).longValue());
} else if (convClassName.equals(“java.math.BigDecimal”)) {
返回 new BigDecimal(((Double) 物件).doubleValue());
}
throwNoSupprt(物件, convClassName);
}
// ———————————“BigDecimal 的物件實例”
else if (BigDecimal 物件實例) {
if (convClassName.equals(“java.lang.String”)) {
返回物件.toString();
} else if (convClassName.equals(“java.lang.Long”)
|| convClassName.equals(“long”)) {
返回 new Long(((BigDecimal) 物件).longValue());
} else if (convClassName.equals(“java.lang.Integer”)
|| convClassName.equals(“int”)) {
傳回新的 Integer(((BigDecimal) 物件).intValue());
}
throwNoSupprt(物件, convClassName);
}
// ——————————————-‘object instanceof byte[]’
else if (物件實例位元組[]) {
if (convClassName.equals(“java.sql.Blob”)) {
返回對象;
}
throwNoSupprt(物件, convClassName);
}
// —————————————————“物件是布林值”
else if (布林物件實例) {
if (convClassName.equals(“boolean”)) {
返回對象;
}
throwNoSupprt(物件, convClassName);
}
// ——————————————-『物件是布林值[]’
else if (物件實例布林[]) {
if (convClassName.equals(“java.lang.String”)) {
布林[] bs = (布林[]) 物件;
StringBuffer buff = new StringBuffer(“[”);
for (int i = 0; i < bs.length; i++) {
buff.append(bs[i] + “,”);
}
buff.deleteCharAt(buff.length() – 1);
buff.append(“]”);
返回 buff.toString();
}
throwNoSupprt(物件, convClassName);
}
throwNoSupprt(物件, convClassName);
返回空值;
}
/**
*如果不支援轉換則拋出異常。
*
* @param object 要轉換的對象
* @param convClassName 要轉換的型別
*/
私有靜態無效 throwNoSupprt(物件對象,字串 convClassName){
String className = (object != null) ? object.getClass().getName()
: “無效的”;
String errorMess = “\n尚不支援此物件的型別轉換處理。\n”
+ ” [ 物件 ] = ” + 物件 + “,[ 物件類型 ] = ” + 類別名
+ “,[convertClass] = ” + convClassName + “”;
拋出新的 UnsupportedOperationException(errorMess);
}
/**
* 將字串[str]的位置[index]處的字元轉換為大寫或小寫。
* <p>
* @param str 要評估的字串
* @param index 指定位置
* @param toCase 轉換為大寫 ⇒ U | u 轉換為小寫 ⇒ L | l
* @return 轉換後的字串
*/
私人靜態字串 convString(字串 str, int 索引, 字串 toCase) {
if (str == null || str.trim().length() == 0) {
返回字串;
} 別的 {
字串 temp = str.substring(索引, 索引 + 1);
if (toCase.equalsIgnoreCase(“u”)) {
暫時 = temp.toUpperCase();
} 別的 {
temp = temp.toLowerCase();
}
StringBuffer tempBuffer = new StringBuffer(str);
tempBuffer.replace(索引,索引+1,暫時);
返回 tempBuffer.toString();
}
}
/**
* 驗證[value]是否為有效值。
*
* @param value 要評估的字串
* @return [true]: 如果不為 null 且不為“”
*/
私人靜態布林 isExist(字串值) {
if (value != null && value.length() != 0) {
返回真;
}
返回假;
}
/**
* 指定格式的java.util.Date類別或其子類
* 轉換為字串。
* @param date 要轉換的java.util.Date類
* @parampattern指定格式
* @return 格式化日期字串
*/
私人靜態字串toStringDate(日期日期,字串模式){
SimpleDateFormat sdFormat = new SimpleDateFormat(pattern);
返回 sdFormat.format(日期);
}
私有靜態 java.sql.Date toSqlDate(String strDate) {
日曆 cal = toCalendar(strDate);
返回SqlDate(cal);
}
私有靜態 java.sql.Date toSqlDate(日曆 cal) {
長 l = cal.getTime().getTime();
返回新的 java.sql.Date(l);
}
/**
* 將長時間值轉換為指定格式的字串。
* @param time 表示目前時間的毫秒數的長值。
* @parampattern指定格式
* @return 格式化日期字串
*/
私人靜態字串toStringDate(長時間,字串模式){
返回StringDate(新日期(時間),模式);
}
/**
* 字串 ⇒ 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”
* @參數strDate
* @返回
*/
私人靜態日曆 toCalendar(String strDate) {
strDate = 格式(strDate);
日曆 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(日曆.HOUR_OF_DAY);
int mm = cal.get(日曆.分鐘);
int ss = cal.get(日曆.SECOND);
int SSS = cal.get(日曆.MILLISECOND);
cal.clear();
cal.set(yyyy, MM – 1, dd);
int len = strDate.length();
開關(長度){
案例10:
休息;
情況 16: // yyyy/MM/dd HH:mm
HH = Integer.parseInt(strDate.substring(11, 13));
mm = Integer.parseInt(strDate.substring(14, 16));
cal.set(日曆.HOUR_OF_DAY, HH);
cal.set(日曆.分鐘,毫米);
休息;
情況 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(日曆.HOUR_OF_DAY, HH);
cal.set(日曆.分鐘,毫米);
cal.set(日曆.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(日曆.HOUR_OF_DAY, HH);
cal.set(日曆.分鐘,毫米);
cal.set(日曆.SECOND, ss);
cal.set(日曆.MILLISECOND, SSS);
休息;
預設:
拋出新的 IllegalStateException(
“此 String 字串無法轉換為日期字串:”
+strDate);
}
返回校準;
}
/**
* 任何日期字串“yyyy/MM/dd”或“yyyy/MM/dd HH:mm:ss”
* 嘗試轉換為格式。
* 範例:03/1/3 ⇒ 2003/01/03
* @參數strDate
* @返回
*/
私有靜態字串格式(字串strDate){
strDate = strDate.trim();
字串 yyyy = null;
字串 MM = null;
字串 dd = null;
字串 HH = 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 結果 = new StringBuffer();
for (int i = 0; token.hasMoreTokens(); i++) {
字串 temp = token.nextToken();
開關(一){
case 0:// 年份部分
yyyy = fillString(strDate, temp, “f”, “20”, 4);
結果.append(yyyy);
休息;
案例 1:// 月份部分
MM = fillString(strDate, temp, “f”, “0”, 2);
結果.append(“/” + MM);
休息;
案例 2:// 日間時段
dd = fillString(strDate, temp, “f”, “0”, 2);
結果.append(“/” + dd);
休息;
案例3://時間部分
HH = fillString(strDate, temp, “f”, “0”, 2);
結果.append(” ” + HH);
休息;
案例 4:// 分鐘部分
mm = fillString(strDate, temp, “f”, “0”, 2);
結果.append(“:”+mm);
休息;
案例5://第二部分
ss = fillString(strDate, temp, “f”, “0”, 2);
結果.append(“:”+ ss);
休息;
case 6:// 毫秒部分
SSS = fillString(strDate, temp, “b”, “0”, 3);
結果.append(“.” + SSS);
休息;
}
}
回傳結果.toString();
}
私有靜態字串 fillString(字串 strDate, 字串 str,
字串位置,字串 addStr,int len) {
if (str.length() > len) {
String mes = strDate + “該String字串無法轉換為日期字串”;
拋出新的 IllegalStateException(mes);
}
返回 fillString(str, 位置, addStr, len);
}
/**
* 將要新增的字串[addStr]加入到[len]中[position]處的字串[str]中
* 插入直至滿。
* <p>
* 範例:String ss = StringUtil.fillString(“aaa”,”b”,”0″,7); ss ⇒ “aaa0000”
*
* *fillString() 插入直到 len 被填滿,但是 addString() 插入 len。
*
* @param str 目標字串
* @param 位置 在 ⇒ F/f 之前插入 ⇒ B/b 之後插入
* @param addStr 要插入的字串
* @param len 要補充的位數
* @return 轉換後的字串。 [str] 為 null 或空文字,[addStr] 設定為 [len]
* 返回插入的結果,直到滿意為止。
*/
私有靜態字串 fillString(字串 str, 字串位置,
字串 addStr, int len) {
StringBuffer 臨時緩衝區 = null;
if (!isExist(str)) {
tempBuffer = 新的 StringBuffer();
for (int i = 0; i < len; i++) {
tempBuffer.append(addStr);
}
返回 tempBuffer.toString();
} else if (str.length() != len) {
tempBuffer = 新的 StringBuffer(str);
while (len > tempBuffer.length()) {
if (position.equalsIgnoreCase(“f”)) {
tempBuffer.insert(0, addStr);
} 別的 {
tempBuffer.append(addStr);
}
}
返回 tempBuffer.toString();
}
返回字串;
}
}