Java反射(Reflection)是Java语言的一个强大特性,它允许程序在运行时动态地检查和操作类、接口、字段和方法。通过反射,程序可以获取类的信息、创建对象、调用方法、访问字段等,而无需在编译时知道这些类的具体实现。这为Java编程带来了极大的灵活性和动态性。
1. Java反射的基本概念
反射的核心是java.lang.Class
类和java.lang.reflect
包中的类(如Field
、Method
、Constructor
等)。以下是反射的主要功能:
1.1 获取类的信息
通过反射,可以获取类的名称、父类、接口、字段、方法等信息。
1.2 创建对象
可以动态地创建类的实例,而无需通过new
关键字。
1.3 调用方法
可以动态地调用类的方法,包括私有方法。
1.4 访问字段
可以动态地访问类的字段,包括私有字段。
1.5 修改访问权限
可以修改字段和方法的访问权限,例如将私有字段或方法变为可访问。
获取class对象的三种方法
1.Class.forName("全类名")
2.类名.class
3.对象.getClass()
package reflect;public class demo {public static void main(String[] args) throws ClassNotFoundException {/*获取class对象的三种方法1.Class.forName("全类名")2.类名.class3.对象.getClass()*///1.第一种Class cls = Class.forName("reflect.Student");//2.第二种Class cls2 = Student.class;//3.第三种Student st = new Student();Class cls3 = st.getClass();}
}
获取构造函数:
package reflect;import java.lang.reflect.Constructor;public class demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {/*获取class对象的三种方法1.Class.forName("全类名")2.类名.class3.对象.getClass()*///1.第一种Class cls = Class.forName("reflect.Student");//2.获取构造方法
// Constructor[] cons = cls.getConstructors();
// for (Constructor con : cons) {
// System.out.println(con);
//
// }//获取全部
// Constructor[] cons = cls.getDeclaredConstructors();
// for (Constructor con : cons) {
// System.out.println(con);
// }//获取单个Constructor con1 = cls.getDeclaredConstructor();System.out.println(con1);Constructor con2 = cls.getDeclaredConstructor(String.class,int.class);System.out.println(con2);//获取参数Constructor con4 = cls.getDeclaredConstructor(String.class,int.class);Parameter[] parameters = con4.getParameters();for(Parameter parameter : parameters){System.out.println(parameter);}
}
获取成员变量:
重写tostring().
@Overridepublic String toString() {return "Student{name='" + name + "', age=" + age + ", gender='" + gender + "'}";}
实现:
package reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;public class demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException {/*获取class成员变量的三种方法1.Field[] getFields() 返回所有公共成员变量对象数组2.Field[] getDeclaredFields()返回所有成员变量对象数组3.Field getField(String name)返回单个公共成员变量对象4.Field getDeclaredField(String name)返回单个成员变量对象Field类创建对象方法void set(Object obj,Object value)赋值Object get(Object obj)获取值*///1.获取字节码文件对象Class cls = Class.forName("reflect.Student");//2.获取成员变量//Field[] fields = cls.getFields();返回公有成员变量Field[] fields = cls.getDeclaredFields();//返回所有成员变量for(Field field : fields){System.out.println(field);}//获取名字Field name = cls.getDeclaredField("name");System.out.println(name);//权限修饰符int modifiers = name.getModifiers();System.out.println(modifiers);//获取名字String n = name.getName();System.out.println(n);//数据类型Class<?> type = name.getType();System.out.println(type);//变量记录的值Student s = new Student("张三", 18, "男");name.setAccessible(true);Object value = name.get(s);System.out.println(value);//修改值name.set(s,"王五");System.out.println(s);}
}
Student.java
package reflect;import java.io.IOError;
import java.io.IOException;public class Student {private String name;private int age;public String gender;public Student(String name, int age,String gender) {this.name = name;this.age = age;this.gender = gender;}public Student() {}public String getName() {return name;}public String getGender() {return gender;}public void setName(String name) {this.name = name;}public void setGender(String gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void sleep(){System.out.println("睡觉");}public void eat(String something,int a){System.out.println("吃" + something);}public String eat(String something) throws IOException {System.out.println("吃" + something);return "man what can i say";}@Overridepublic String toString() {return "Student{name='" + name + "', age=" + age + ", gender='" + gender + "'}";}
}
Demo.java
package reflect;import javax.swing.text.Style;
import java.lang.reflect.*;
import java.util.Objects;public class demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException {/*获取class成员方法的三种方法1.Method[] getMethods()返回所有公共方法对象数组2.Method[] getDeclaredMethods()返回所有成员变量对象数组3.Method[] getMethod(String name,class<?>)返回单个公共成员变量对象4.Method[] getDeclaredMethod(String name,class<?>)返回单个成员变量对象*///1.获取字节码文件对象Class cls = Class.forName("reflect.Student");//2.获取方法对象(私有)
// Method[] methods = cls.getMethods();
// for(Method method : methods){
// System.out.println(method);
// }Method m = cls.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);}//方法抛出与异常Class [] exceptionTypes = m.getExceptionTypes();for(Class exceptionType : exceptionTypes){System.out.println(exceptionType);}//方法运行/*参数一:obj调用方法参数二:调用方法传递的参数返回值:方法的返回值*/Student s = new Student();//参数一s,调用者 二 红烧肉 实参m.setAccessible(true);Object result = m.invoke(s,"红烧肉");//返回值System.out.println(result);}
}