基于上一篇,我们简单介绍了反射以及如何获取class文件对象和如何利用反射获取构造方法,接下来,我们就来说一说反射获取的另外两种,获取成员变量和成员方法。
首先是利用反射获取成员变量
对比上篇的构造方法,大家有没有发现前面几乎只是变量和方法的区别,其他几乎一样?
话不多说,直接代码演示
首先,依旧是创建一个Student类,封装其javabean
package com.ittaotao.myreflect3;
public class Student {
private String name;
private int age;
public String gender;
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
返回成员变量
package com.ittaotao.myreflect3;
import java.lang.reflect.Field;
public class MyReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
//1.首先,咱们依旧是要获取字节码文件的对象
Class clazz = Class.forName("com.ittaotao.myreflect3.Student");
//2.获取里面的成员变量对象(公共的成员变量对象)
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("---------------------");
//2.获取里面的成员变量对象(包括私有的成员变量对象)
Field[] fields2 = clazz.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
System.out.println("---------------------");
//3.获取单个的成员变量
Field gender = clazz.getField("gender");
System.out.println(gender);
System.out.println("---------------------");
//4.获取私有的成员变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
}
}
运行结果
获取权限修饰符、名字、数据类型、成员变量记录的值,同时我们也可以修改对象里面的值
//5.获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);
System.out.println("---------------------");
//6.获取成员变量名字
String n = name.getName();
System.out.println(n);
System.out.println("---------------------");
//7.获取数据类型
Class type = name.getType();
System.out.println(type);
System.out.println("---------------------");
//获取成员变量记录的值
//因为其与对象有关,所以,想要获取值,首先要先创建一个对象
Student s = new Student("zhangsan",23,"男");
name.setAccessible(true);
String value = (String) name.get(s);
System.out.println(value);
System.out.println("---------------------");
//修改对象里面的值--把s对象里面的name修改成lisi
name.set(s,"lisi");
System.out.println(s);
以上就是利用反射获取成员变量的一些方法了
最后,我们来说一下利用反射获取成员方法
我们可以发现获取方法的规律都是一样的
废话不多说,直接代码演示
首先一样,我们先创建student类,不过这次我们加了sleep和eat方法
package com.ittaotao.myreflect4;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println("睡觉");
}
public void eat(String something){
System.out.println("在吃" + something);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
首先,获取里面所有的方法对象(包含父类中所有的公共方法)
package com.ittaotao.myreflect4;
import java.lang.reflect.Method;
public class MyReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//1.获取class字节码文件对象
Class clazz = Class.forName("com.ittaotao.myreflect4.Student");
//2.获取里面所有的方法对象
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
获取里面所有的方法对象(不能获取父类的,但是可以获取本类中私有的方法)
//获取里面所有的方法对象(不能获取父类的,但是可以获取本类中私有的方法)
Method[]methods1 = clazz.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(method);
}
返回单个成员方法对象
//因为eat方法是私有的,所以我们要用getDeclaredMethod方法进行调用
Method m = clazz.getDeclaredMethod("eat",String.class);
System.out.println(m);
获取方法的修饰符
//获取方法的修饰符
int modifiers = m.getModifiers();
System.out.println(modifiers);
获取方法的名字
//获取方法的名字
String name = m.getName();
System.out.println(name);
获取方法的形参
//获取方法的形参
Parameter[] parameters = m.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
获取方法的抛出的异常
//获取方法抛出的异常 这里我们需要在student代码中加入异常
Class[] exceptionTypes = m.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {
System.out.println(exceptionType);
}
获取方法并运行
//方法运行
/*
* Method类中用于创建对象的方法
* Object invoke(Object obj,Object...agrs):运行方法
* 参数一:用obj对象调用方法
* 参数二:调用方法的传递的参数(如果没有就不写)
* 返回值:方法的返回值(如果没有就不写)
* */
Student s = new Student();
m.setAccessible(true);
//参数一s:表示方法的调用者
//参数二“汉堡包”:表示在调用方法的时候传递的实际参数
m.invoke(s,"汉堡包");
倘若有返回值,student类需要进行修改
public String eat(String something) throws IOException,NullPointerException,ClassCastException {
System.out.println("在吃" + something);
return "奥利给";
}
Student s = new Student();
m.setAccessible(true);
//参数一s:表示方法的调用者
//参数二“汉堡包”:表示在调用方法的时候传递的实际参数
Object result = m.invoke(s, "汉堡包");
System.out.println(result);
运行结果如下
以上就是java中所有的反射了,如有问题还请评论区多多指教!