Java 反射
反射(Reflection)
- 反射就是:加载类,并且允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。
获取类的信息并且操作类
- 1.反射第一步:加载类,获取类的字节码:Class对象
- 2.获取类的构造器:Constructor对象
- 3.获取类的成员变量:Field对象
- 4.获取类的成员方法:Method对象
获取Class对象的三种方式
- Class c1 = 类名.class
- 调用Class提供方法:public static Class forName(String package);
- Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Object.class;
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
Class c2 = Class.forName("java.lang.Object");
System.out.println(c1==c2);
Object obj = new Object();
Class c3 = obj.getClass();
System.out.println(c3 == c2);
}
运行结果
java.lang.Object
Object
true
true
定义Students类
class Student{
private String name;
private int age;
public int publicName;
public Student(){
System.out.println("无参构造");
}
public Student(int a){
System.out.println("有参构造");
}
Student(int a,int b){
System.out.println("default修饰有参构造");
}
private Student(int a, int b, int c){
System.out.println("private修饰有参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private void run(){
System.out.println("私密方法运行");
}
}
获取类的构造器
public class Reflection {
public static void getAll(){
// 1.反射第一步:必须得到这个类的Class对象
Class<Student> c = Student.class;
// 2.获取类的全部构造器
// getConstructors只能获取public修饰的全部构造器
// Constructor[] constructors = c.getConstructors();
// getDeclaredConstructors可以获取所有存在的构造器
Constructor[] constructors = c.getDeclaredConstructors();
// 3.遍历数组中的每个构造器对象
for (Constructor constructor : constructors){
System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());
}
}
public static void getOne() throws Exception {
// 1.反射第一步:必须得到这个类的Class对象
Class c = Student.class;
// 2.获取类的某个构造器
// getConstructor只能获取public修饰的单个构造器
// Constructor<Student> constructor = c.getConstructor();
// getDeclaredConstructor可以单个存在的构造器
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());
// 3.获取有参数构造器
Constructor constructor1 = c.getDeclaredConstructor(int.class);
System.out.println(constructor1.getName() + "---->" + constructor1.getParameterCount());
}
public static void main(String[] args) throws Exception {
getAll();
System.out.println("----------------------");
getOne();
}
}
运行结果
study.Student---->3
study.Student---->2
study.Student---->1
study.Student---->0
----------------------
study.Student---->0
study.Student---->1
类构造器的作用
- setAccessible(true)禁止检查访问控制(可以破坏封装性)
- newInstance()执行构造器的方法
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class c = Student.class;
Constructor constructor = c.getDeclaredConstructor();
constructor.newInstance();
Constructor constructor1 = c.getDeclaredConstructor(int.class,int.class,int.class);
constructor1.setAccessible(true);
constructor1.newInstance(1,2,3);
}
运行结果
无参构造
private修饰有参构造
获取类的成员变量
- setAccessible(true)禁止检查访问控制(可以破坏封装性)
- set 赋值
- get 取值
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
// 1.反射第一步:必须是先得到类的Class对象
Class studentClass = Student.class;
System.out.println(studentClass.getName());
System.out.println("------------------------");
// 2.获取类的全部成员变量
// getFields获取类的全部public修饰的成员变量
Field[] publicFields = studentClass.getFields();
for (Field field : publicFields){
System.out.println("public成员变量:" + field.getName() + "--->" + field.getType());
}
System.out.println("------------------------");
// getDeclaredFields获取类的全部存在成员变量
Field[] Fields = studentClass.getDeclaredFields();
for (Field field : Fields){
System.out.println("所有成员变量:" + field.getName() + "--->" + field.getType());
}
System.out.println("------------------------");
// 3.定位某个成员变量
{
Field field = studentClass.getDeclaredField("name");
System.out.println("所有成员变量:" + field.getName() + "--->" + field.getType());
System.out.println("------------------------");
// 赋值
Student student = new Student();
field.setAccessible(true); // 禁止访问控制权限
field.set(student,"暴力赋值");
System.out.println(student.getName());
System.out.println("------------------------");
//取值
String name = (String) field.get(student);
System.out.println(name);
}
}
运行结果
------------------------
public成员变量:publicName--->int
------------------------
所有成员变量:name--->class java.lang.String
所有成员变量:age--->int
所有成员变量:publicName--->int
------------------------
所有成员变量:name--->class java.lang.String
------------------------
无参构造
暴力赋值
------------------------
暴力赋值
获取类的成员方法
- setAccessible(true)禁止检查访问控制(可以破坏封装性)
- invoke(),执行方法,括号内必须传入类的对象
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class c = Student.class;
// getMethods获取所有public修饰的成员方法
Method[] publicMethods = c.getMethods();
// getDeclaredMethods获取所有存在的成员方法
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName() + "----" + method.getParameterCount() + "----" + method.getReturnType());
}
System.out.println("-------------------------");
Student student = new Student();
Method run = c.getDeclaredMethod("run");
run.setAccessible(true);
run.invoke(student);
System.out.println("-------------------------");
Method setName = c.getDeclaredMethod("setName", String.class);
setName.invoke(student,"方法赋值");
Method getName = c.getDeclaredMethod("getName");
System.out.println(getName.invoke(student));;
}
运行结果
getName----0----class java.lang.String
run----0----void
setName----1----void
-------------------------
无参构造
私密方法运行
-------------------------
方法赋值
评论 (0)