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();
}
返回字符串;;
}
}
