整理Java反射常用方法
来源:互联网 发布:神盾内网管理软件 编辑:程序博客网 时间:2024/06/08 13:54
Class相关
Class获取的3种方式:
package com.dl7.studydemo;public class MyClass {//}//1Class<?> cls1 = MyClass.class;//2MyClass myClass = new MyClass();Class<?> cls2 = myClass.getClass();//3Class<?> cls3 = null;try { cls3 = Class.forName("com.dl7.studydemo.MyClass");} catch (ClassNotFoundException e) { e.printStackTrace();}
获取父类:
public Class<? super T> getSuperclass();
获取内部类:
/** * 获取类中本身定义的公共、私有、保护的内部类 */public Class<?>[] getDeclaredClasses();/** * 获取类本身和其父类定义的公共、私有、保护的内部类 */public Class<?>[] getClasses();内部类获取定义它的外部类:
/** * 获取定义它的外部类,如果为匿名内部类则返回null */public Class<?> getDeclaringClass();/** * 获取定义它的外部类,匿名内部类同样有效 */public Class<?> getEnclosingClass();
Field相关
通过Class获取Field:
/** * 获取类本身的所有字段,包括公有、保护、私有 */public native Field[] getDeclaredFields();/** * 获取类本身和其所有父类的公有和保护字段 */public Field[] getFields();/** * 获取类本身的指定字段,包括公有、保护、私有 * @param name字段名 */public native Field getDeclaredField(String name) throws NoSuchFieldException;/** * 获取类本身和其所有父类指定的公有和保护字段 * @param name字段名 */public Field getField(String name) throws NoSuchFieldException;
Field的相关属性:
/** * 获取字段的作用域:public、protected、private、abstract、static、final ... */Modifier.toString(field.getModifiers());/** * 获取字段的类型,配合getSimpleName()使用:int、long、String ... */field.getType().getSimpleName();/** * 获取字段名称 */field.getName();
Field提供了一系列的getter和setter方法来对变量进行访问控制:
public native Object get(Object object) throws IllegalAccessException, IllegalArgumentException;public native boolean getBoolean(Object object) throws IllegalAccessException, IllegalArgumentException;public native byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException;public native char getChar(Object object) throws IllegalAccessException, IllegalArgumentException;public native double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException;public native float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException;public native int getInt(Object object) throws IllegalAccessException, IllegalArgumentException;public native long getLong(Object object) throws IllegalAccessException, IllegalArgumentException;public native short getShort(Object object) throws IllegalAccessException, IllegalArgumentException;public native void set(Object object, Object value) throws IllegalAccessException, IllegalArgumentException;public native void setBoolean(Object object, boolean value) throws IllegalAccessException, IllegalArgumentException;public native void setByte(Object object, byte value) throws IllegalAccessException, IllegalArgumentException;public native void setChar(Object object, char value) throws IllegalAccessException, IllegalArgumentException;public native void setDouble(Object object, double value) throws IllegalAccessException, IllegalArgumentException;public native void setFloat(Object object, float value) throws IllegalAccessException, IllegalArgumentException;public native void setInt(Object object, int value) throws IllegalAccessException, IllegalArgumentException;public native void setLong(Object object, long value) throws IllegalAccessException, IllegalArgumentException;public native void setShort(Object object, short value) throws IllegalAccessException, IllegalArgumentException;这里有两点要说明:
1. 每个方法里头都有一个Object参数,对于非静态字段来说,它必须设置为具体的实例,而对于静态字段来说它没有实际意义,可设为null;
2. 对于私有(private)字段,在进行访问的时候需要先调用 field.setAccessible(true),而公有、保护字段可直接进行访问;
其实联系下我们平时对访问权限的控制还是很好理解的,静态变量和具体实例无关,私有变量外部不能访问。
使用方式:
MyClass myClass = new MyClass();Class<?> cls = myClass.getClass();// 获取私有域Field field = cls.getDeclaredField("myPrivateInt");// 如果为静态变量可按以下调用field.setAccessible(true);field.getInt(null);field.setInt(null, 33);// 如果为非静态变量则必须按以下调用field.setAccessible(true);field.getInt(myClass);field.setInt(myClass, 33);
Method相关
通过Class获取Method:
/** * 获取类本身的所有方法,包括公有、保护、私有 */public Method[] getDeclaredMethods();/** * 获取类本身和其所有父类的公有和保护方法 */public Method[] getMethods();/** * 获取类本身的指定方法,包括公有、保护、私有 * @param name方法名 * @param parameterTypes参数类型 */public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException;/** * 获取类本身和其所有父类指定的公有和保护方法 * @param name方法名 * @param parameterTypes参数类型 */public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException;
通过Class获取构造方法:
/** * 获取类本身的所有构造方法,包括公有、保护、私有 */public Constructor<?>[] getDeclaredConstructors();/** * 获取类本身非私有构造方法 */public Constructor<?>[] getConstructors();/** * 获取类本身指定的构造方法 * @param parameterTypes参数类型 */public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException;/** * 获取类本身指定的非私有构造方法 * @param parameterTypes参数类型 */public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException;
Method的常用属性,构造方法没有返回值属性:
/** * 获取方法的作用域:public、protected、private、abstract、static、final ... */Modifier.toString(method.getModifiers());/** * 获取方法的返回值类型,配合getSimpleName()使用:int、long、String ... */method.getReturnType().getSimpleName();/** * 获取方法名称 */method.getName();/** * 获取方法参数 */Class<?>[] parameterTypes = method.getParameterTypes();/** * 获取方法声明所在类 */method.getDeclaringClass();
执行方法:
/** * 执行方法 */public native Object invoke(Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;/** * 执行构造方法 */public native T newInstance(Object... args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;注意,和访问字段一样,会受到静态和私有等属性的影响,对于私有记得先加上 method.setAccessible(true),参考Field的访问。
这里有个反射工具类:
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.Collection;import java.util.List;/** * 反射工具类,提供一些Java基本的反射功能 */public class ReflectUtils { public static final Class<?>[] EMPTY_PARAM_TYPES = new Class<?>[0]; public static final Object[] EMPTY_PARAMS = new Object[0];/* ************************************************** 字段相关的方法 ******************************************************* */ /** * 从指定的类中获取指定的字段 * * @param sourceClass 指定的类 * @param fieldName 要获取的字段的名字 * @param isFindDeclaredField 是否查找Declared字段 * @param isUpwardFind 是否向上去其父类中寻找 * @return */ public static Field getField(Class<?> sourceClass, String fieldName, boolean isFindDeclaredField, boolean isUpwardFind) { Field field = null; try { field = isFindDeclaredField ? sourceClass.getDeclaredField(fieldName) : sourceClass.getField(fieldName); } catch (NoSuchFieldException e1) { if (isUpwardFind) { Class<?> classs = sourceClass.getSuperclass(); while (field == null && classs != null) { try { field = isFindDeclaredField ? classs.getDeclaredField(fieldName) : classs.getField(fieldName); } catch (NoSuchFieldException e11) { classs = classs.getSuperclass(); } } } } return field; } /** * 从指定的类中获取指定的字段,默认获取Declared类型的字段、向上查找 * * @param sourceClass 指定的类 * @param fieldName 要获取的字段的名字 * @return */ public static Field getField(Class<?> sourceClass, String fieldName) { return getField(sourceClass, fieldName, true, true); } /** * 获取给定类的所有字段 * * @param sourceClass 给定的类 * @param isGetDeclaredField 是否需要获取Declared字段 * @param isGetParentField 是否需要把其父类中的字段也取出 * @param isGetAllParentField 是否需要把所有父类中的字段全取出 * @param isDESCGet 在最终获取的列表里,父类的字段是否需要排在子类的前面。只有需要把其父类中的字段也取出时此参数才有效 * @return 给定类的所有字段 */ public static List<Field> getFields(Class<?> sourceClass, boolean isGetDeclaredField, boolean isGetParentField, boolean isGetAllParentField, boolean isDESCGet) { List<Field> fieldList = new ArrayList<Field>(); //如果需要从父类中获取 if (isGetParentField) { //获取当前类的所有父类 List<Class<?>> classList = null; if (isGetAllParentField) { classList = getSuperClasss(sourceClass, true); } else { classList = new ArrayList<Class<?>>(2); classList.add(sourceClass); Class<?> superClass = sourceClass.getSuperclass(); if (superClass != null) { classList.add(superClass); } } //如果是降序获取 if (isDESCGet) { for (int w = classList.size() - 1; w > -1; w--) { for (Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields() : classList.get(w).getFields()) { fieldList.add(field); } } } else { for (int w = 0; w < classList.size(); w++) { for (Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields() : classList.get(w).getFields()) { fieldList.add(field); } } } } else { for (Field field : isGetDeclaredField ? sourceClass.getDeclaredFields() : sourceClass.getFields()) { fieldList.add(field); } } return fieldList; } /** * 获取给定类的所有字段 * * @param sourceClass 给定的类 * @return 给定类的所有字段 */ public static List<Field> getFields(Class<?> sourceClass) { return getFields(sourceClass, true, true, true, true); } /** * 设置给定的对象中给定名称的字段的值 * * @param object 给定的对象 * @param fieldName 要设置的字段的名称 * @param newValue 要设置的字段的值 * @param isFindDeclaredField 是否查找Declared字段 * @param isUpwardFind 如果在当前类中找不到的话,是否取其父类中查找 * @return 设置是否成功。false:字段不存在或新的值与字段的类型不一样,导致转型失败 */ public static boolean setField(Object object, String fieldName, Object newValue, boolean isFindDeclaredField, boolean isUpwardFind) { boolean result = false; Field field = getField(object.getClass(), fieldName, isFindDeclaredField, isUpwardFind); if (field != null) { try { field.setAccessible(true); field.set(object, newValue); result = true; } catch (IllegalAccessException e) { e.printStackTrace(); result = false; } } return result; }/* ************************************************** 方法相关的方法 ******************************************************* */ /** * 从指定的类中获取指定的方法 * * @param sourceClass 给定的类 * @param isFindDeclaredMethod 是否查找Declared字段 * @param isUpwardFind 是否向上去其父类中寻找 * @param methodName 要获取的方法的名字 * @param methodParameterTypes 方法参数类型 * @return 给定的类中给定名称以及给定参数类型的方法 */ public static Method getMethod(Class<?> sourceClass, boolean isFindDeclaredMethod, boolean isUpwardFind, String methodName, Class<?>... methodParameterTypes) { Method method = null; try { method = isFindDeclaredMethod ? sourceClass.getDeclaredMethod(methodName, methodParameterTypes) : sourceClass.getMethod(methodName, methodParameterTypes); } catch (NoSuchMethodException e1) { if (isUpwardFind) { Class<?> classs = sourceClass.getSuperclass(); while (method == null && classs != null) { try { method = isFindDeclaredMethod ? classs.getDeclaredMethod(methodName, methodParameterTypes) : classs.getMethod(methodName, methodParameterTypes); } catch (NoSuchMethodException e11) { classs = classs.getSuperclass(); } } } } return method; } /** * 从指定的类中获取指定的方法,默认获取Declared类型的方法、向上查找 * * @param sourceClass 指定的类 * @param methodName 方法名 * @param methodParameterTypes 方法参数类型 * @return */ public static Method getMethod(Class<?> sourceClass, String methodName, Class<?>... methodParameterTypes) { return getMethod(sourceClass, true, true, methodName, methodParameterTypes); } /** * 从指定的类中获取指定名称的不带任何参数的方法,默认获取Declared类型的方法并且向上查找 * * @param sourceClass 指定的类 * @param methodName 方法名 * @return */ public static Method getMethod(Class<?> sourceClass, String methodName) { return getMethod(sourceClass, methodName, EMPTY_PARAM_TYPES); } /** * 获取给定类的所有方法 * * @param clas 给定的类 * @param isGetDeclaredMethod 是否需要获取Declared方法 * @param isFromSuperClassGet 是否需要把其父类中的方法也取出 * @param isDESCGet 在最终获取的列表里,父类的方法是否需要排在子类的前面。只有需要把其父类中的方法也取出时此参数才有效 * @return 给定类的所有方法 */ public static List<Method> getMethods(Class<?> clas, boolean isGetDeclaredMethod, boolean isFromSuperClassGet, boolean isDESCGet) { List<Method> methodList = new ArrayList<Method>(); //如果需要从父类中获取 if (isFromSuperClassGet) { //获取当前类的所有父类 List<Class<?>> classList = getSuperClasss(clas, true); //如果是降序获取 if (isDESCGet) { for (int w = classList.size() - 1; w > -1; w--) { for (Method method : isGetDeclaredMethod ? classList.get(w).getDeclaredMethods() : classList.get(w).getMethods()) { methodList.add(method); } } } else { for (int w = 0; w < classList.size(); w++) { for (Method method : isGetDeclaredMethod ? classList.get(w).getDeclaredMethods() : classList.get(w).getMethods()) { methodList.add(method); } } } } else { for (Method method : isGetDeclaredMethod ? clas.getDeclaredMethods() : clas.getMethods()) { methodList.add(method); } } return methodList; } /** * 获取给定类的所有方法 * * @param sourceClass 给定的类 * @return 给定类的所有方法 */ public static List<Method> getMethods(Class<?> sourceClass) { return getMethods(sourceClass, true, true, true); } /** * 获取给定的类中指定参数类型的ValuOf方法 * * @param sourceClass 给定的类 * @param methodParameterTypes 方法参数类型 * @return 给定的类中给定名称的字段的GET方法 */ public static Method getValueOfMethod(Class<?> sourceClass, Class<?>... methodParameterTypes) { return getMethod(sourceClass, true, true, "valueOf", methodParameterTypes); } /** * 调用不带参数的方法 * * @param method * @param object * @return * @throws Exception */ public static Object invokeMethod(Method method, Object object) throws Exception { return method.invoke(object, EMPTY_PARAMS); }/* ************************************************** 构造函数相关的方法 ******************************************************* */ /** * 获取给定的类中给定参数类型的构造函数 * * @param sourceClass 给定的类 * @param isFindDeclaredConstructor 是否查找Declared构造函数 * @param isUpwardFind 是否向上去其父类中寻找 * @param constructorParameterTypes 构造函数的参数类型 * @return 给定的类中给定参数类型的构造函数 */ public static Constructor<?> getConstructor(Class<?> sourceClass, boolean isFindDeclaredConstructor, boolean isUpwardFind, Class<?>... constructorParameterTypes) { Constructor<?> method = null; try { method = isFindDeclaredConstructor ? sourceClass.getDeclaredConstructor(constructorParameterTypes) : sourceClass.getConstructor(constructorParameterTypes); } catch (NoSuchMethodException e1) { if (isUpwardFind) { Class<?> classs = sourceClass.getSuperclass(); while (method == null && classs != null) { try { method = isFindDeclaredConstructor ? sourceClass.getDeclaredConstructor(constructorParameterTypes) : sourceClass.getConstructor(constructorParameterTypes); } catch (NoSuchMethodException e11) { classs = classs.getSuperclass(); } } } } return method; } /** * 获取给定的类中所有的构造函数 * * @param sourceClass 给定的类 * @param isFindDeclaredConstructor 是否需要获取Declared构造函数 * @param isFromSuperClassGet 是否需要把其父类中的构造函数也取出 * @param isDESCGet 在最终获取的列表里,父类的构造函数是否需要排在子类的前面。只有需要把其父类中的构造函数也取出时此参数才有效 * @return 给定的类中所有的构造函数 */ public static List<Constructor<?>> getConstructors(Class<?> sourceClass, boolean isFindDeclaredConstructor, boolean isFromSuperClassGet, boolean isDESCGet) { List<Constructor<?>> constructorList = new ArrayList<Constructor<?>>(); //如果需要从父类中获取 if (isFromSuperClassGet) { //获取当前类的所有父类 List<Class<?>> classList = getSuperClasss(sourceClass, true); //如果是降序获取 if (isDESCGet) { for (int w = classList.size() - 1; w > -1; w--) { for (Constructor<?> constructor : isFindDeclaredConstructor ? classList.get(w).getDeclaredConstructors() : classList.get(w).getConstructors()) { constructorList.add(constructor); } } } else { for (int w = 0; w < classList.size(); w++) { for (Constructor<?> constructor : isFindDeclaredConstructor ? classList.get(w).getDeclaredConstructors() : classList.get(w).getConstructors()) { constructorList.add(constructor); } } } } else { for (Constructor<?> constructor : isFindDeclaredConstructor ? sourceClass.getDeclaredConstructors() : sourceClass.getConstructors()) { constructorList.add(constructor); } } return constructorList; }/* ************************************************** 父类相关的方法 ******************************************************* */ /** * 获取给定的类所有的父类 * * @param sourceClass 给定的类 * @param isAddCurrentClass 是否将当年类放在最终返回的父类列表的首位 * @return 给定的类所有的父类 */ public static List<Class<?>> getSuperClasss(Class<?> sourceClass, boolean isAddCurrentClass) { List<Class<?>> classList = new ArrayList<Class<?>>(); Class<?> classs; if (isAddCurrentClass) { classs = sourceClass; } else { classs = sourceClass.getSuperclass(); } while (classs != null) { classList.add(classs); classs = classs.getSuperclass(); } return classList; }/* ************************************************** 其它的辅助方法 ******************************************************* */ /** * 获取给定的类的名字 * * @param sourceClass 给定的类 * @return 给定的类的名字 */ public static String getClassName(Class<?> sourceClass) { String classPath = sourceClass.getName(); return classPath.substring(classPath.lastIndexOf('.') + 1); } @SuppressWarnings("unchecked") public static <T> T getObjectByFieldName(Object object, String fieldName, Class<T> clas) { if (object != null && StringUtils.isNotEmpty(fieldName) && clas != null) { try { Field field = ReflectUtils.getField(object.getClass(), fieldName, true, true); if (field != null) { field.setAccessible(true); return (T) field.get(object); } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } else { return null; } } /** * 判断给定字段是否是type类型的数组 * * @param field * @param type * @return */ public static final boolean isArrayByType(Field field, Class<?> type) { Class<?> fieldType = field.getType(); return fieldType.isArray() && type.isAssignableFrom(fieldType.getComponentType()); } /** * 判断给定字段是否是type类型的collectionType集合,例如collectionType=List.class,type=Date.class就是要判断给定字段是否是Date类型的List * * @param field * @param collectionType * @param type * @return */ @SuppressWarnings("rawtypes") public static final boolean isCollectionByType(Field field, Class<? extends Collection> collectionType, Class<?> type) { Class<?> fieldType = field.getType(); if (collectionType.isAssignableFrom(fieldType)) { Class<?> first = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; return type.isAssignableFrom(first); } else { return false; } }}
0 0
- 整理Java反射常用方法
- Java反射常用方法
- java 反射常用方法
- JAVA反射常用方法
- java反射常用方法
- Java 常用方法整理
- java 常用的反射方法
- JAVA反射机制常用方法
- JAVA反射--一些常用方法
- Java 反射常用方法示例
- Java反射机制常用方法
- java 反射常用方法(面试常见)
- Java反射机制常用方法介绍
- 浅谈Java反射(Reflect)技术--常用方法
- Java反射机制-Class类常用方法
- 反射方法整理
- Java反射复习整理
- [整理]Java 反射[待续]
- 【hdu5747】Aaronson——popcount
- ECshop 页面修改及出错处理方法基础知识(第一部分)
- HTTP状态码
- HDU 1823 Luck and Love (二维线段树模板)
- AS3.0的元素处理(二)-- TextField
- 整理Java反射常用方法
- Spring中你不知道的注入方式
- Sqlite3 数据库操作
- TCP的三次握手和四次挥手
- caffe 编译中出现的错误——fatal error: hdf5.h: 没有那个文件或目录
- C++ RGB图片对比度调整
- 资讯:警用无人机路在何方?
- Mysql与sql server的区别
- lintcode paint-fence 栅栏染色