Day43 Java反射(二)

2024-05-05 22:04
文章标签 java 反射 day43

本文主要是介绍Day43 Java反射(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Day43 Java反射(二)

文章目录

  • Day43 Java反射(二)
    • 一、利用反射操作方法
    • 二、利用反射操作方法里的参数和返回值
    • 三、利用反射操作泛型
    • 四、利用反射操作注解
    • 五、利用反射操作数组

一、利用反射操作方法

1、基本步骤

  1. 获取Class对象:要操作一个类,首先需要获取对应的Class对象。可以通过类名.class语法或者Class.forName(“类名”)方法来获取。
  2. 获取类的构造函数:通过Class对象可以获取类的构造函数,从而实例化对象。
  3. 获取类的字段(属性):可以通过Class对象的getFields()、getDeclaredFields()等方法获取类的字段信息,从而访问和修改这些字段的值。
  4. 获取类的方法:可以通过Class对象的getMethods()、getDeclaredMethods()等方法获取类的方法信息,从而调用这些方法。
  5. 调用方法:通过Method类的invoke()方法可以调用类的方法。
  6. 访问和修改字段:通过Field类的get()和set()方法可以访问和修改类的字段的值。
  7. 处理异常:在使用反射时,需要处理可能抛出的IllegalAccessException、IllegalArgumentException、InvocationTargetException等异常

2、示例代码:

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、常用方法:

  1. 获取方法参数信息
    • 使用Method类的getParameterTypes()方法可以获取方法的参数类型,返回一个Class数组,每个元素代表一个参数的类型。
    • 使用Method类的getParameters()方法可以获取方法的参数信息,返回一个Parameter数组,每个元素包含参数的名称、修饰符等信息。
  2. 调用方法
    • 使用Method类的invoke()方法可以调用方法,并传入对应的参数值。需要注意参数的类型要与方法定义的参数类型一致,否则会抛出IllegalArgumentException异常。
  3. 获取返回值类型
    • 使用Method类的getReturnType()方法可以获取方法的返回值类型,返回一个Class对象,表示返回值的类型。
  4. 处理返回值
    • 调用Method类的invoke()方法后会返回方法的执行结果,需要根据返回值类型进行相应的处理,可以使用instanceof关键字进行类型检查,然后进行强制类型转换

总的来说,通过反射机制可以动态地获取和操作方法的参数和返回值信息,这为编写通用的、灵活的代码提供了便利。但是在处理参数和返回值时,需要注意类型匹配和异常处理,以确保程序的正确性和稳定性。

2、示例代码:

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、常用方法:

  1. 获取泛型类型信息
    • 可以通过反射获取包含泛型信息的类、方法或字段的Type对象,例如ParameterizedType、TypeVariable等。
    • 使用Type类的getTypeName()方法可以获取泛型类型的名称,进而分析泛型参数的具体类型。
  2. 操作泛型类
    • 可以通过Class类的getGenericSuperclass()方法获取泛型父类的Type信息,从而获取泛型参数的具体类型。
    • 使用Class类的getTypeParameters()方法可以获取类声明的泛型参数信息。
  3. 操作泛型方法
    • 可以通过Method类的getGenericReturnType()、getGenericParameterTypes()等方法获取方法的泛型返回类型和参数类型信息。
  4. 操作泛型字段
    • 可以通过Field类的getGenericType()方法获取字段的泛型类型信息。
  5. 创建泛型实例
    • 可以通过ParameterizedTypeImpl类等来创建泛型实例,从而实现对泛型类型的操作和实例化。

2、示例代码:

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、常用方法:

  1. 获取类、方法、字段上的注解
    • 使用Class类的getAnnotation()方法可以获取类上的指定注解。
    • 使用Method类的getAnnotation()方法可以获取方法上的指定注解。
    • 使用Field类的getAnnotation()方法可以获取字段上的指定注解。
  2. 判断注解的存在
    • 使用isAnnotationPresent()方法可以判断类、方法、字段上是否存在指定的注解。
  3. 获取注解的属性值
    • 获取到注解对象后,可以通过注解对象的方法来获取注解的属性值,例如@Retention、@Target等元注解的属性值。
  4. 根据注解信息进行处理
    • 根据注解的存在与内容,可以编写相应的逻辑来处理。例如,根据注解标记的方法执行特定的操作,或者根据注解的属性值进行不同的处理。
  5. 动态生成带有注解的类、方法、字段
    • 可以通过反射机制动态生成带有注解的类、方法、字段,并在运行时进行相应的处理。

2、示例代码:

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、常用方法:

  1. 创建数组实例
    • 使用Array类的newInstance()方法可以动态创建数组实例,指定数组的类型和长度。
  2. 获取数组的长度
    • 使用Array类的getLength()方法可以获取数组的长度。
  3. 访问和修改数组元素
    • 使用Array类的get()方法可以访问数组指定位置的元素。
    • 使用Array类的set()方法可以修改数组指定位置的元素。
  4. 处理多维数组
    • 对于多维数组,可以使用Array类的newInstance()方法创建多维数组实例,通过多次调用get()和set()方法来访问和修改多维数组的元素。
  5. 数组类型检查
    • 在使用反射操作数组时,需要注意数组元素的类型,确保类型匹配,避免出现ClassCastException等异常。

2、示例代码:

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);}}
}

态创建数组实例,指定数组的类型和长度。
2. 获取数组的长度

  • 使用Array类的getLength()方法可以获取数组的长度。
  1. 访问和修改数组元素
    • 使用Array类的get()方法可以访问数组指定位置的元素。
    • 使用Array类的set()方法可以修改数组指定位置的元素。
  2. 处理多维数组
    • 对于多维数组,可以使用Array类的newInstance()方法创建多维数组实例,通过多次调用get()和set()方法来访问和修改多维数组的元素。
  3. 数组类型检查
    • 在使用反射操作数组时,需要注意数组元素的类型,确保类型匹配,避免出现ClassCastException等异常。

2、示例代码:

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);}}
}

这篇关于Day43 Java反射(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962784

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2