Day43 Java反射(二)
文章目录
- [Day43 Java反射(二)](#Day43 Java反射(二))
一、利用反射操作方法
1、基本步骤
- 获取Class对象:要操作一个类,首先需要获取对应的Class对象。可以通过类名.class语法或者Class.forName("类名")方法来获取。
- 获取类的构造函数:通过Class对象可以获取类的构造函数,从而实例化对象。
- 获取类的字段(属性):可以通过Class对象的getFields()、getDeclaredFields()等方法获取类的字段信息,从而访问和修改这些字段的值。
- 获取类的方法:可以通过Class对象的getMethods()、getDeclaredMethods()等方法获取类的方法信息,从而调用这些方法。
- 调用方法:通过Method类的invoke()方法可以调用类的方法。
- 访问和修改字段:通过Field类的get()和set()方法可以访问和修改类的字段的值。
- 处理异常:在使用反射时,需要处理可能抛出的IllegalAccessException、IllegalArgumentException、InvocationTargetException等异常
2、示例代码:
java
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Properties;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import com.qf.utils.ReflexUtil;
public class Test01 {
/**
* 知识点:利用反射操作方法
*/
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException {
Properties p = new Properties();
p.load(Test01.class.getClassLoader().getResourceAsStream("classPath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//获取本类及其父类公有的方法对象
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//获取本类所有的方法对象
Method[] methods1 = clazz.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(method);
}
//获取本类及其父类所有的方法对象
for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
Method[] methods2 = c.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
}
//获取本类公有的指定名字的方法对象
Method method = clazz.getMethod("setClassId", String.class);
System.out.println(method);
//获取本类所有的指定名字的方法对象
Method method1 = clazz.getDeclaredMethod("method");
System.out.println(method1);
//利用反射工具类获取子类及其父类指定名字的方法对象
Method method2 = ReflexUtil.getMethod(clazz, "method");
System.out.println(method2);
//获取方法参数值
int modifiers = method.getModifiers();
System.out.println("是否使用public修饰:" + Modifier.isPublic(modifiers));
System.out.println("是否使用private修饰:" + Modifier.isPrivate(modifiers));
System.out.println("是否使用protected修饰:" + Modifier.isProtected(modifiers));
System.out.println("是否使用static修饰:" + Modifier.isStatic(modifiers));
System.out.println("是否使用final修饰:" + Modifier.isFinal(modifiers));
System.out.println("是否使用abstract修饰:" + Modifier.isAbstract(modifiers));
System.out.println("是否使用synchronized修饰:" + Modifier.isSynchronized(modifiers));
}
}
public class ReflexUtil {
/**
* 获取当前类及其父类的属性对象
* @param clazz class对象
* @param name 属性名
* @return 属性对象
*/
public static Field getField(Class<?> clazz,String name){
for(Class<?> c = clazz;c != null;c = c.getSuperclass()){
try {
Field field = c.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 设置对象中的属性
* @param obj 对象
* @param name 属性名
* @param value 属性值
*/
public static void setField(Object obj,String name,Object value){
Field field = getField(obj.getClass(), name);
if(field != null){
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 创建对象
* @param clazz class对象
* @param paremeterType 构造方法中的参数类型数组
* @param paremeters 构造方法中的参数数据
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paremeters){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T obj = constructor.newInstance(paremeters);
return obj;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取方法对象
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @return 方法对象
*/
public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){
for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
try {
Method method = c.getDeclaredMethod(name, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 调用成员方法
* @param obj 对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Object obj,String name,Class<?>[] parameterTypes,Object[] paremeters){
Class<? extends Object> clazz = obj.getClass();
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
/**
* 调用静态方法
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Class<?> clazz,String name,Class<?>[] parameterTypes,Object[] paremeters){
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
}
二、利用反射操作方法里的参数和返回值
在利用反射操作方法时,可以通过反射机制获取方法的参数信息和返回值类型。
1、常用方法:
- 获取方法参数信息 :
- 使用Method类的getParameterTypes()方法可以获取方法的参数类型,返回一个Class数组,每个元素代表一个参数的类型。
- 使用Method类的getParameters()方法可以获取方法的参数信息,返回一个Parameter数组,每个元素包含参数的名称、修饰符等信息。
- 调用方法 :
- 使用Method类的invoke()方法可以调用方法,并传入对应的参数值。需要注意参数的类型要与方法定义的参数类型一致,否则会抛出IllegalArgumentException异常。
- 获取返回值类型 :
- 使用Method类的getReturnType()方法可以获取方法的返回值类型,返回一个Class对象,表示返回值的类型。
- 处理返回值 :
- 调用Method类的invoke()方法后会返回方法的执行结果,需要根据返回值类型进行相应的处理,可以使用instanceof关键字进行类型检查,然后进行强制类型转换
总的来说,通过反射机制可以动态地获取和操作方法的参数和返回值信息,这为编写通用的、灵活的代码提供了便利。但是在处理参数和返回值时,需要注意类型匹配和异常处理,以确保程序的正确性和稳定性。
2、示例代码:
java
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.Properties;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import com.qf.utils.ReflexUtil;
public class Test03 {
/**
* 知识点:利用反射操作 方法里的参数和返回值
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Properties p = new Properties();
p.load(Test03.class.getClassLoader().getResourceAsStream("classPath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//利用反射工具类获取方法对象
Method method = ReflexUtil.getMethod(clazz, "method04", String.class,int.class);
//获取方法的参数个数
int parameterCount = method.getParameterCount();
System.out.println("获取方法的参数个数:" + parameterCount);
System.out.println("-----------------------------");
//获取方法参数的class对象数组
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> c : parameterTypes) {
System.out.println(c);
}
System.out.println("-----------------------------");
//获取方法参数的Type对象数组
//一个参数类型就是一个Type对象
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type type : genericParameterTypes) {
System.out.println(type);
}
System.out.println("-----------------------------");
//获取方法参数对象数组
//一个参数就是一个参数对象
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
System.out.println("获取方法的参数类型:" + parameter.getType());
/**
* 注意:
* 参数名不会随着编译而编译到class文件,
* class文件描述该方法的参数名使用的是:arg0,arg1,arg2,.....
*/
System.out.println("获取方法的参数名:" + parameter.getName());
}
System.out.println("-----------------------------");
//获取返回值的class对象
Class<?> returnType = method.getReturnType();
System.out.println("获取返回值的class对象:" + returnType);
//获取返回值的Type对象
Type genericReturnType = method.getGenericReturnType();
System.out.println("获取返回值的Type对象:" + genericReturnType);
}
}
public class ReflexUtil {
/**
* 获取当前类及其父类的属性对象
* @param clazz class对象
* @param name 属性名
* @return 属性对象
*/
public static Field getField(Class<?> clazz,String name){
for(Class<?> c = clazz;c != null;c = c.getSuperclass()){
try {
Field field = c.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 设置对象中的属性
* @param obj 对象
* @param name 属性名
* @param value 属性值
*/
public static void setField(Object obj,String name,Object value){
Field field = getField(obj.getClass(), name);
if(field != null){
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 创建对象
* @param clazz class对象
* @param paremeterType 构造方法中的参数类型数组
* @param paremeters 构造方法中的参数数据
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paremeters){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T obj = constructor.newInstance(paremeters);
return obj;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取方法对象
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @return 方法对象
*/
public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){
for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
try {
Method method = c.getDeclaredMethod(name, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 调用成员方法
* @param obj 对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Object obj,String name,Class<?>[] parameterTypes,Object[] paremeters){
Class<? extends Object> clazz = obj.getClass();
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
/**
* 调用静态方法
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Class<?> clazz,String name,Class<?>[] parameterTypes,Object[] paremeters){
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
}
三、利用反射操作泛型
在Java中,由于泛型的类型擦除特性,直接使用反射来操作泛型可能会遇到一些限制和困难。然而,仍然可以通过一些技巧和方法来处理泛型类型。
注意 :
类上的泛型是获取不到的,因为不固定!!!
class A{}
1、常用方法:
- 获取泛型类型信息 :
- 可以通过反射获取包含泛型信息的类、方法或字段的Type对象,例如ParameterizedType、TypeVariable等。
- 使用Type类的getTypeName()方法可以获取泛型类型的名称,进而分析泛型参数的具体类型。
- 操作泛型类 :
- 可以通过Class类的getGenericSuperclass()方法获取泛型父类的Type信息,从而获取泛型参数的具体类型。
- 使用Class类的getTypeParameters()方法可以获取类声明的泛型参数信息。
- 操作泛型方法 :
- 可以通过Method类的getGenericReturnType()、getGenericParameterTypes()等方法获取方法的泛型返回类型和参数类型信息。
- 操作泛型字段 :
- 可以通过Field类的getGenericType()方法获取字段的泛型类型信息。
- 创建泛型实例 :
- 可以通过ParameterizedTypeImpl类等来创建泛型实例,从而实现对泛型类型的操作和实例化。
2、示例代码:
java
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import com.qf.utils.ReflexUtil;
public class Test04 {
/**
* 知识点:利用反射操作泛型
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Properties p = new Properties();
p.load(Test04.class.getClassLoader().getResourceAsStream("classPath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//获取属性上的泛型类型
Field field = ReflexUtil.getField(clazz, "map");
Type fieldType = field.getGenericType();
ParameterizedType fieldTypepPT = (ParameterizedType) fieldType;
Type[] actualTypeArguments = fieldTypepPT.getActualTypeArguments();//获取泛型类型
for (Type type : actualTypeArguments) {
System.out.println(type);
}
System.out.println("---------------------------------------");
Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);
//获取方法上参数的泛型类型
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
Type parameterizedType = parameter.getParameterizedType();
ParameterizedType parameterTypepPT = (ParameterizedType) parameterizedType;
Type[] actualTypeArguments2 = parameterTypepPT.getActualTypeArguments();
for (Type type : actualTypeArguments2) {
System.out.println(type);
}
}
System.out.println("---------------------------------------");
//获取方法上返回值的泛型类型
Type genericReturnType = method.getGenericReturnType();
ParameterizedType returnPT = (ParameterizedType) genericReturnType;
Type[] actualTypeArguments2 = returnPT.getActualTypeArguments();
for (Type type : actualTypeArguments2) {
System.out.println(type);
}
}
}
public class ReflexUtil {
/**
* 获取当前类及其父类的属性对象
* @param clazz class对象
* @param name 属性名
* @return 属性对象
*/
public static Field getField(Class<?> clazz,String name){
for(Class<?> c = clazz;c != null;c = c.getSuperclass()){
try {
Field field = c.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 设置对象中的属性
* @param obj 对象
* @param name 属性名
* @param value 属性值
*/
public static void setField(Object obj,String name,Object value){
Field field = getField(obj.getClass(), name);
if(field != null){
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 创建对象
* @param clazz class对象
* @param paremeterType 构造方法中的参数类型数组
* @param paremeters 构造方法中的参数数据
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paremeters){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T obj = constructor.newInstance(paremeters);
return obj;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取方法对象
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @return 方法对象
*/
public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){
for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
try {
Method method = c.getDeclaredMethod(name, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 调用成员方法
* @param obj 对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Object obj,String name,Class<?>[] parameterTypes,Object[] paremeters){
Class<? extends Object> clazz = obj.getClass();
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
/**
* 调用静态方法
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Class<?> clazz,String name,Class<?>[] parameterTypes,Object[] paremeters){
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
}
四、利用反射操作注解
在Java中,可以利用反射机制来操作注解,包括获取类、方法、字段等上的注解信息,判断注解的存在与内容,以及根据注解信息进行相应的处理。
1、常用方法:
- 获取类、方法、字段上的注解 :
- 使用Class类的getAnnotation()方法可以获取类上的指定注解。
- 使用Method类的getAnnotation()方法可以获取方法上的指定注解。
- 使用Field类的getAnnotation()方法可以获取字段上的指定注解。
- 判断注解的存在 :
- 使用isAnnotationPresent()方法可以判断类、方法、字段上是否存在指定的注解。
- 获取注解的属性值 :
- 获取到注解对象后,可以通过注解对象的方法来获取注解的属性值,例如@Retention、@Target等元注解的属性值。
- 根据注解信息进行处理 :
- 根据注解的存在与内容,可以编写相应的逻辑来处理。例如,根据注解标记的方法执行特定的操作,或者根据注解的属性值进行不同的处理。
- 动态生成带有注解的类、方法、字段 :
- 可以通过反射机制动态生成带有注解的类、方法、字段,并在运行时进行相应的处理。
2、示例代码:
java
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import com.qf.utils.ReflexUtil;
public class Test05 {
/**
* 知识点:利用反射操作注解
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Properties p = new Properties();
p.load(Test05.class.getClassLoader().getResourceAsStream("classPath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//获取类上的注解信息
MyAnnotaction classAnnotation = clazz.getAnnotation(MyAnnotaction.class);
System.out.println(classAnnotation.str());
System.out.println("------------------------------------------------");
//获取属性上的注解信息
Field field = ReflexUtil.getField(clazz, "map");
MyAnnotaction fieldAnnotation = field.getAnnotation(MyAnnotaction.class);
System.out.println(fieldAnnotation.str());
System.out.println("------------------------------------------------");
//获取方法上的注解信息
Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);
MyAnnotaction methodAnnotation = method.getAnnotation(MyAnnotaction.class);
System.out.println(methodAnnotation.str());
System.out.println("------------------------------------------------");
//获取参数上的注解信息
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
MyAnnotaction parameterAnnotation = parameter.getAnnotation(MyAnnotaction.class);
if(parameterAnnotation != null){//说明该参数上有MyAnnotaction的注解
System.out.println(parameterAnnotation.str());
}
}
}
}
public class ReflexUtil {
/**
* 获取当前类及其父类的属性对象
* @param clazz class对象
* @param name 属性名
* @return 属性对象
*/
public static Field getField(Class<?> clazz,String name){
for(Class<?> c = clazz;c != null;c = c.getSuperclass()){
try {
Field field = c.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 设置对象中的属性
* @param obj 对象
* @param name 属性名
* @param value 属性值
*/
public static void setField(Object obj,String name,Object value){
Field field = getField(obj.getClass(), name);
if(field != null){
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 创建对象
* @param clazz class对象
* @param paremeterType 构造方法中的参数类型数组
* @param paremeters 构造方法中的参数数据
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paremeters){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T obj = constructor.newInstance(paremeters);
return obj;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取方法对象
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @return 方法对象
*/
public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){
for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
try {
Method method = c.getDeclaredMethod(name, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 调用成员方法
* @param obj 对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Object obj,String name,Class<?>[] parameterTypes,Object[] paremeters){
Class<? extends Object> clazz = obj.getClass();
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
/**
* 调用静态方法
* @param clazz class对象
* @param name 方法名
* @param parameterTypes 参数列表数组
* @param paremeters 参数数据数组
* @return 方法返回值
*/
public static Object invoke(Class<?> clazz,String name,Class<?>[] parameterTypes,Object[] paremeters){
Method method = getMethod(clazz, name, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, paremeters);
return invoke;
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
return null;
}
}
五、利用反射操作数组
在Java中,可以利用反射机制来操作数组,包括创建数组实例、获取数组的长度、访问和修改数组元素等操作。
注意:Array -- 该类是Java给我们提供专门利用反射去操作数组的类
1、常用方法:
- 创建数组实例 :
- 使用Array类的newInstance()方法可以动态创建数组实例,指定数组的类型和长度。
- 获取数组的长度 :
- 使用Array类的getLength()方法可以获取数组的长度。
- 访问和修改数组元素 :
- 使用Array类的get()方法可以访问数组指定位置的元素。
- 使用Array类的set()方法可以修改数组指定位置的元素。
- 处理多维数组 :
- 对于多维数组,可以使用Array类的newInstance()方法创建多维数组实例,通过多次调用get()和set()方法来访问和修改多维数组的元素。
- 数组类型检查 :
- 在使用反射操作数组时,需要注意数组元素的类型,确保类型匹配,避免出现ClassCastException等异常。
2、示例代码:
java
import java.lang.reflect.Array;
public class Test06 {
/**
* 知识点:利用反射操作数组
*
*/
public static void main(String[] args) {
//创建数组
int[] arr = (int[]) Array.newInstance(int.class, 10);
//获取数组长度
int length = Array.getLength(arr);
System.out.println("获取数组长度:" + length);
//循环设置每个下标上的元素
for (int i = 0; i < Array.getLength(arr); i++) {
//设置当前下标上的元素
Array.set(arr, i, i+1);
}
//循环获取每个下标上的元素
for (int i = 0; i < Array.getLength(arr); i++) {
//获取当前下标上的元素
Object element = Array.get(arr, i);
System.out.println(element);
}
}
}
态创建数组实例,指定数组的类型和长度。
- 获取数组的长度:
- 使用Array类的getLength()方法可以获取数组的长度。
- 访问和修改数组元素 :
- 使用Array类的get()方法可以访问数组指定位置的元素。
- 使用Array类的set()方法可以修改数组指定位置的元素。
- 处理多维数组 :
- 对于多维数组,可以使用Array类的newInstance()方法创建多维数组实例,通过多次调用get()和set()方法来访问和修改多维数组的元素。
- 数组类型检查 :
- 在使用反射操作数组时,需要注意数组元素的类型,确保类型匹配,避免出现ClassCastException等异常。
2、示例代码:
java
import java.lang.reflect.Array;
public class Test06 {
/**
* 知识点:利用反射操作数组
*
*/
public static void main(String[] args) {
//创建数组
int[] arr = (int[]) Array.newInstance(int.class, 10);
//获取数组长度
int length = Array.getLength(arr);
System.out.println("获取数组长度:" + length);
//循环设置每个下标上的元素
for (int i = 0; i < Array.getLength(arr); i++) {
//设置当前下标上的元素
Array.set(arr, i, i+1);
}
//循环获取每个下标上的元素
for (int i = 0; i < Array.getLength(arr); i++) {
//获取当前下标上的元素
Object element = Array.get(arr, i);
System.out.println(element);
}
}
}