反射机制 概述

反射

1.什么是反射?

正射:知道某个类,类的地址,通过new关键字创建出对象,而后使用对象。

但是对于框架来说,处理哪些类并不知道,只结合它类的地址,他就能够获取类的信息,创建对象,动态调用对象的属性和方法,(通过反射机制通过类的地址加载出任何类的信息)这种使用类的方式称为反向使用类,这种机制就叫做反射。

之前也接触过这样的反射机制

xml配置中的通过访问地址来获取类对象

resultType="com.****.***.***.类名"

jdbc中的

class.forName("com.mysql.cj.jdbc.Driver");

类名

Class clazz=User.class;
反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

反射就是把java类中的各种成分映射成一个个的Java对象

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)

API中给出的class(类)的解释

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odWV7INf-1657943770793)(D:\反射\QQ截图20220716103032.png)]

扫描二维码关注公众号,回复: 15784151 查看本文章

2.反射的作用

通过反射可以使程序代码访问到JVM中的类的内部信息

  • 获取已经装载类的属性信息
  • 获取已经装载的类的方法
  • 获取已经装载的类的构造方法

3.反射的使用

1、获取Class对象的三种方式

1.1 Object ——> getClass();

1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性

1.3 通过Class类的静态方法:forName(String className)(常用)

package com.ffyc.mybatisdemo.reflectDemo;

public class Test {
    
    
	public static void main(String[] args) throws ClassNotFoundException {
    
    
		User user = new User();//正向的使用类
		/*
		* 反射的根基是能拿到类的class对象
		* */
		Class clazz1=new User().getClass();//通过getClass()方法得到该对象类Class后,可以通过Class获取这个类中的相关属性和方法;
		Class clazz2=User.class;
		Class clazz3=Class.forName("com.ffyc.mybatisdemo.reflectDemo.User");
		System.out.println(clazz1==clazz2);//拿到的都是同一个User对象
		System.out.println(clazz1==clazz3);
	}
}

2.通过反射获取构造方法

2.1,获得共有的构造方法

//得到无参构造(公有的)
Constructor constructor = clazz.getConstructor();
//得到有参构造(共有的)
Constructor constructor = clazz.getConstructor(int.class, String.class);
//调用构造方法
Object obj = constructor.newInstance();

2.2,获得私有的构造方法

//获得私有的构造方法
Constructor constructor = clazz.getDeclaredConstructor();
//得到所有的构造方法
Constructor[] conArray = clazz.getDeclaredConstructors(int.class, String.class);
constructor.setAccessible(true);//设置私有属性操作权(暴力操作),会破坏java的封装结构不建议使用
Object obj = constructor.newInstance(1,"admin");
3.获得成员变量并调用
 /* 获取成员变量并调用:
 * 
 * 1.批量的
 * 		1).Field[] getFields():获取所有的"公有字段"
 * 		2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
 * 2.获取单个的:
 * 		1).public Field getField(String fieldName):获取某个"公有的"字段;
 * 		2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
 * 
 * 	 设置字段的值:
 * 		Field --> public void set(Object obj,Object value):
 * 					参数说明:
 * 					1.obj:要设置的字段所在的对象;
 * 					2.value:要为字段设置的值;
 */
 public class Fields {
    
    
 
		public static void main(String[] args) throws Exception {
    
    
			//1.获取Class对象
			Class stuClass = Class.forName("com.ffyc.mybatisdemo.reflectDemo.User");
			//2.获取字段
			System.out.println("************获取所有公有的字段********************");
			Field[] fieldArray = stuClass.getFields();
			for(Field f : fieldArray){
    
    
				System.out.println(f);
			}
			System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
			fieldArray = stuClass.getDeclaredFields();
			for(Field f : fieldArray){
    
    
				System.out.println(f);
			}
			System.out.println("*************获取公有字段**并调用***********************************");
			Field f = stuClass.getField("name");
			System.out.println(f);
	}
}

4.获得成员方法并调用

/* 获取成员方法并调用:
 * 
 * 1.批量的:
 * 		public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
 * 		public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
 * 2.获取单个的:
 * 		public Method getMethod(String name,Class<?>... parameterTypes):
 * 					参数:
 * 						name : 方法名;
 * 						Class ... : 形参的Class类型对象
 * 		public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
 * 
 * 	 调用方法:
 * 		Method --> public Object invoke(Object obj,Object... args):
 * 					参数说明:
 * 					obj : 要调用方法的对象;
 * 					args:调用方式时所传递的实参;
*/
public class MethodClass {
    
    
 
	public static void main(String[] args) throws Exception {
    
    
		//1.获取Class对象
		Class stuClass = Class.forName("com.ffyc.mybatisdemo.reflectDemo.User");
		//2.获取所有公有方法
		System.out.println("***************获取所有的”公有“方法*******************");
		stuClass.getMethods();
		Method[] methodArray = stuClass.getMethods();
		for(Method m : methodArray){
    
    
			System.out.println(m);
		}
		System.out.println("***************获取所有的方法,包括私有的*******************");
		methodArray = stuClass.getDeclaredMethods();
		for(Method m : methodArray){
    
    
			System.out.println(m);
		}
        //在已知方法名的条件下获取get方法
		System.out.println("***************获取get()方法*******************");
		Method getId = aClass.getMethod("getId");//在知道方法名的条件下
		System.out.println(getId);
		Method[] methods = aClass.getDeclaredMethods();//获取所有的方法
		for(Method method:methods){
    
    
			System.out.println(method);
		}
        //在不知道方法名的条件下获得get,set方法
		Field[] fields = aClass.getDeclaredFields();
		String s="{";
		for(Field field:fields){
    
    
			Method method = aClass.getMethod("get" + 					String.valueOf(field.getName().charAt(0)).toUpperCase() +
					field.getName().substring(1));
			Object obj=
            aClass.getDeclaredConstructor(int.class,String.class).newInstance(1,"admin");
			s+=field.getName()+":"+method.invoke(obj)+",";
		}
		s+="}";
		System.out.println(s);
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_52340450/article/details/125818117