java反射常用方法案例详解
作者:祁_z
1.反射概述
Java反射指的是一个机制,这种机制可以在Java程序运行时(动态)实例化对象、读写属性、调用方法。
关键词:运行时
一般在我们开发程序时,都知道自己具体用的什么类,直接创建即可。但是当写一些通用的功能时,就不能在编译时把具体类的类型写死,因为程序运行起来后可能会有多种类型的可能,此时就需要在运行时动态的去调用某个类的属性和方法,这就必须通过反射来实现。
案例:
// 不知道调用者传入什么类型对象。 public static String instance(Object obj) { …… }
如何知道方法的参数Object是什么类型?
一般有两种做法:
第一种做法:是知道参数类型有哪几种情况,可以使用instanceof运算符进行判断,再利用强制类型转换将其转换成其运行时类型的变量即可。
public static String getTypeInstanceof(Object obj){ // 学生 if (obj instanceof Student){ Student student = (Student) obj; String userType = student.getUserType("王明"); return userType; } // 老师 if (obj instanceof Teacher){ Teacher teacher = (Teacher) obj; String userType = teacher.getUserType("王明"); return userType; } return null; }
第二种做法:在编译时根本无法预知该对象和类可能属于哪些类,程序只依靠运行时信息动态的来发现该对象和类的真实信息,这就必须使用反射。
public static String getType(Object obj) { // 通过反射获取运行时类 Class<?> aClass = obj.getClass(); try { // 实例化对象 Object instance = aClass.newInstance(); // 调用getUserType方法 // 匹配对象中的getUserType()方法,参数类型为String Method method02 = aClass.getMethod("getUserType", String.class); // 调用匹配的方法,传入参数 String invoke = (String) method02.invoke(instance, "王明"); return invoke; } catch (InstantiationException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; }
案例全部代码:
public class Demo1 { public static void main(String[] args) { // 测试Instanceof方式 Teacher teacher = new Teacher(); String typeInstanceof = getTypeInstanceof(teacher); System.out.println(typeInstanceof); // 测试反射方式 Student student = new Student(); String type = getType(student); System.out.println(type); } public static String getTypeInstanceof(Object obj){ // 学生 if (obj instanceof Student){ Student student = (Student) obj; String userType = student.getUserType("王明"); return userType; } // 老师 if (obj instanceof Teacher){ Teacher teacher = (Teacher) obj; String userType = teacher.getUserType("王明"); return userType; } return null; } /** * 获取用户类型方法(老师、学生...) */ public static String getType(Object obj) { // 通过反射获取运行时类 Class<?> aClass = obj.getClass(); try { // 实例化对象 Object instance = aClass.newInstance(); // 调用getUserType方法 // 匹配对象中的getUserType()方法,参数类型为String Method method02 = aClass.getMethod("getUserType", String.class); // 调用匹配的方法,传入参数 String invoke = (String) method02.invoke(instance, "王明"); return invoke; } catch (InstantiationException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 学生类 */ static class Student { public String getUserType(String str) { System.out.println(str); return "学生-" + str; } } /** * 老师类 */ static class Teacher { public String getUserType(String str) { System.out.println(str); return "老师-" + str; } } }
2. 反射获取Class对象的三种方式
通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象。
方式一:Class.forName("包名.类名") - 常用方式
例如:Class.forName("com.kexuekt.Student");
方式二:使用类的class属性来获取该类对应的Class对象
例如: Student.class;
方式三:调用对象的getClass()方法,该方法是Object类中的方法,因为每个类默认继承了Object类,所有的Java对象都可以调用该方法
例如:
Student stu = new Student();
stu.getClass();
3.反射常用方法
3.1反射获取构造方法
- Constructor<?>[] getDeclaredConstructors():获取所有构造方法
- Constructor<?>[] getConstructors():获取所有public构造方法
- Constructor<T> getConstructor():获取无参构造方法
- Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):根据参数类型获取有参构造方法
- 创建实例化对象方法 T newInstance(Object... initargs):根据指定的构造方法创建对象
3.2反射获取成员变量
- Field[] getDeclaredFields():获取所有成员变量
- Field getDeclaredField(String name):获取单个成员变量
- Field[] getFields():获取所有public成员变量
- Field getField(String name):获取单个public成员变量
- Field类中用于给成员变量赋值的方法void set(Object obj, Object value):给obj对象的成员变量赋值为value
私有成员变量设置值,需要取消访问权限检查 Field.setAccessible(true);
3.3反射获取成员方法
- Method[] getMethods():获取所有public成员方法,包括继承的
- Method[] getDeclaredMethods():获取所有成员方法,不包括继承的
- Method getMethod(String name, Class<?>... parameterTypes) :获取单个public成员方法
- Method getDeclaredMethod(String name, Class<?>... parameterTypes):获取单个成员方法
- Method类中用于调用成员方法的方法Object invoke(Object obj, Object... args):调用obj对象的成员方法,参数是args,返回值是Object类型
3.4反射获取构造、成员变量、成员方法Demo
学生类
class Student { private String name; public Integer age; public Student(){ } public Student(String name, Integer age){ this.name = name; this.age = age; } private String getUserType(String str) { System.out.println(str); return "学生-" + str; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
获取构造方法Demo
获取无参构造方法
Class aClass = Student.class; Constructor constructor = aClass.getConstructor(); Student newInstance = (Student)constructor.newInstance();
根据参数类型获取有参构造方法
// 根据参数类型获取构造方法 Class aClass = Student.class; Class<?>[] classes = {Class.forName("java.lang.String"), Class.forName("java.lang.Integer")}; Constructor c = aClass.getDeclaredConstructor(classes); Student student = (Student)c.newInstance("王明", 1); System.out.println(student.toString());
获取成员变量方法
获取所有成员变量方法
Class aClass = Student.class; Field[] fields = aClass.getDeclaredFields(); for (Field field : fields) { System.out.println(field.getName()); }
获取指定成员变量方法
Class aClass = Student.class; Field name = aClass.getDeclaredField("name");
给private、public成员变量赋值
// 获取name私有成员变量 Field name = aClass.getDeclaredField("name"); name.setAccessible(true); // 获取age成员变量 Field age = aClass.getDeclaredField("age"); // 通过反射实例化对象 Student student = aClass.getConstructor().newInstance(); // 成员变量参数赋值 name.set(student, "王明"); age.set(student, 20); System.out.println(student.toString());
获取成员方法
获取本类中所有成员方法
Class aClass = Student.class; Method[] methods = aClass.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()); }
调用成员方法
// 获取私有成员方法 Method getUserType = aClass.getDeclaredMethod("getUserType", Class.forName("java.lang.String")); // 关闭权限检查 getUserType.setAccessible(true); // 实例化对象 Student student = aClass.getConstructor().newInstance(); // 调用方法,传入参数 Object invoke = getUserType.invoke(student, "王亮"); System.out.println(invoke);
到此这篇关于java反射常用方法的文章就介绍到这了,更多相关java反射常用方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!