Java反射(安排的明明白白)

反射是框架设计的灵魂

一、什么是反射

反射是一种机制/功能,利用该机制/功能可以在程序运行过程中对类进行解剖并操作类中的构造方法,成员方
法,成员属性。
简而言之:反射就是把Java的各种成分(字段,方法)映射成相应的Java类

二、常见应用场景

  • 1.最常见的就是编译器给出的提示
    在这里插入图片描述
  • 2.SSH | SSM框架的设计大量使用了反射机制

三、获取Class的三种方法

  • 对象.getClass()
  • 使用Class类的forName(“类的全限定名”) 最常见的方式
  • 使用“类.class”
		Class<?> c1 = null;
        Class<?> c2 = null;
        Class<?> c3 = null;
        c2 = new Object().getClass();
        c1 = Class.forName("com.mine.test.Demo_01");
        c3 = Object.class;

四、获取Class对象的信息

  • 获取简单类名
String getSimpleName(); 获取简单类名,只是类名,没有包
  • 获取完整类名
String getSimpleName(); 获取简单类名,只是类名,没有包
  • 创建对象(依赖无参构造)
String getSimpleName(); 获取简单类名,只是类名,没有包

Demo

//b. 字节码对象里面常见的方法
public void fun02() throws Exception {
	//1. Class.forName("类的全限定名");
	//Class clazz = Class.forName("com.itheima.bean.Student");
	Class clazz = Student.class;
	//2. 获得类名(简单类名) Student
	System.out.println(clazz.getSimpleName());
	//3. 获得完整的类名 com.itheima.bean.Student
	System.out.println(clazz.getName());
	//4. 通过字节码创建对象(要求: 依赖的是无参构造)‐‐ new Student();
	Student student = (Student) clazz.newInstance();
	student.speak();
}

五、构造函数的反射

Constructor是构造方法类,类中的每一个构造方法都是Constructor的对象,通过Constructor对象可以实例
化对象。

  • Class类中与Constructor相关方法
clazz.getDeclaredConstructors(); //获得所有的构造方法(包含私有的)
clazz.getConstructor(Class... paramType); //获得特定的构造方法
constructor.newInstance(Object...params);// 根据构造方法创建对象

Demo

//c. 反射构造方法
public void fun03() throws Exception {
	//1. Class.forName("类的全限定名");
	Class clazz = Class.forName("com.itheima.bean.Student");
	//2. 获得所有的构造方法(包含私有的)
	Constructor[] constructors = clazz.getDeclaredConstructors();
	System.out.println(constructors.length);
	//3. 反射获得某一个特定的构造方法
	//eg: public Student(String name, int age, String sex)
	Constructor constructor = clazz.getConstructor(String.class, int.class, String.class);
	Student student = (Student) constructor.newInstance("张三",18,"男");//根据构造方法创建一个
	对象
	System.out.println(student.getAge());
}

六、属性的反射

Field是属性类,类中的每一个属性都是Field的对象,通过Field对象可以给对应的属性赋值和取值。

  • Class类中与Field相关方法
1.  Field[] getFields()
	获取所有的public修饰的属性对象,返回数组
2.  Field[] getDeclaredFields()
	获取所有的属性对象,包括private修饰的,返回数组
3.  Field getField(String name)
	根据属性名获得属性对象,只能获取public修饰的
4.  Field getDeclaredField(String name)
	根据属性名获得属性对象,包括private修饰的
  • Field类中常用方法
set(obj,value);通用方法都是给对象obj的属性设置使用
get(obj); 通用方法是获取对象obj对应的属性值的
void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性

Demo

//d. 反射字段
public void fun04() throws Exception {
	Student student = new Student("张三", 18, "男");
	//1. Class.forName("类的全限定名");
	Class clazz = Class.forName("com.itheima.bean.Student");
	//2. 获得所有的字段(包含私有的)
	Field[] fields = clazz.getDeclaredFields();
	//System.out.println(fields.length);
	for (Field field : fields) {
	//取值
	//field.get()
	//设置值
	//field.set();
	}
	//3. 获得某一个特定的字段 String name;
	Field nameFiled = clazz.getDeclaredField("name");
	nameFiled.setAccessible(true);//暴力破解(可以访问私有的字段或者方法)
	//取值
	Object nameValue = nameFiled.get(student);
	System.out.println(nameValue);
	//赋值
	nameFiled.set(student,"李四");
	System.out.println(student.getName());
}

七、方法的反射

Method是方法类,类中的每一个方法都是Method的对象,通过Method对象可以调用方法。

  • Class类中与Method相关方法
1.  Method[] getMethods()
	获取所有的public修饰的成员方法,包括父类中
2.  Method[] getDeclaredMethods()
	获取当前类中所有的方法,包含私有的,不包括父类中
3.  Method getMethod("方法名", 方法的参数类型... 类型)
	根据方法名和参数类型获得一个方法对象,只能是获取public修饰的
4.  Method getDeclaredMethod("方法名", 方法的参数类型... 类型)
	根据方法名和参数类型获得一个方法对象,包括private修饰的
  • Method类中常用方法
1.  Object invoke(Object obj, Object... args)
	根据参数args调用对象obj的该成员方法
	如果obj=null,则表示该方法是静态方法
2.  void setAccessible(true)
	暴力反射,设置为可以直接调用私有修饰的成员方法

Demo

@Test
//d. 反射方法
public void fun05() throws Exception {
	//1. 获得字节码
	Class clazz = Class.forName("com.itheima.bean.Student");
	//2. 获得公共的方法(包含父类的)
	Method[] methods = clazz.getMethods();
	for (Method method : methods) {
	//System.out.println("方法名="+method.getName());
	}
	//3. 获得所有的方法(包含私有的,但是不包含父类的)
	Method[] declaredMethods = clazz.getDeclaredMethods();
	for (Method method : declaredMethods) {
	//System.out.println("方法名="+method.getName());
	}
	//4. 反射某一个特点的方法
	//eg:public void speak()
	Method method = clazz.getMethod("speak");
	//method.invoke(clazz.newInstance());
	//eg: private void speak(String name)
	Method declaredMethod = clazz.getDeclaredMethod("speak", String.class);
	declaredMethod.setAccessible(true);//暴力破解
	declaredMethod.invoke(clazz.newInstance(),"李四");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值