反射

一、Class的理解

1.Class是反射的源头 (要想使用反射必先获取该类的Class对象)
2.Class本身也是一个类
3.Class 对象只能由系统建立对象
4.一个加载的类在 JVM 中只会一个Class实例
5.一个Class对象对应的是一个加载到JVM中的一个.class文件
6.每个类的实例都会记得自己是由哪个 Class 实例所生成
7.通过Class可以完整地得到一个类中的所有被加载的结构
8.Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯先获得相应的Class对象

二、获取Class的实例

//1.获取Class实例的方式一 : 类名.class
Class clazz = Person.class;
//2.获取Class实例的方式二 :对象名.getClass()
Class clazz2 = new Person().getClass();
//3.获取Class实例的方式 : Class.forName(全类名)
Class clazz3 = Class.forName("com.atguigu.java2.Person");
//4.获取Class实例的方式四 : 类加器.loadClass(全类名) - 了解
ClassLoader c = this.getClass().getClassLoader();
Class clazz4 = c.loadClass("com.atguigu.java2.Person");

三、了解ClassLoader

在这里插入图片描述

四、反射的应用

	/*
	 * 通过反射获取指定属性并赋值 - 需要掌握
	 */
	@Test
	public void test3() throws Exception, Exception{
		//创建Dog对象
		Dog dog = new Dog();
		
		Class clazz = Dog.class;
		//获取指定属性
		/*
		 * getField() : 只能获取public所修饰的属性
		 */
//		Field field = clazz.getField("dogAge");
		//给属性赋值
		/*
		 * setInt(对象名,属性值)
		 */
//		field.setInt(dog, 10);
		
		System.out.println("------------------给私属性赋值----------------------------");
		
		//获取指定的属性
		/*
		 * getDeclaredField() : 可以获取任意权限修饰符修饰的属性
		 */
		Field declaredField = clazz.getDeclaredField("dogName");
		//授权(设置是否允许访问
		declaredField.setAccessible(true);
		//给属性赋值
		declaredField.set(dog, "中华田园犬");
		
		dog.test();
		
	}
	
	/*
	 * 调用指定的方法 - 需要掌握
	 */
	@Test
	public void test4() throws Exception, Exception{
		
		Dog dog = new Dog();
		
		Class clazz = Dog.class;
		
		//获取指定的方法
		/*
		 * 第一个参数 :方法名
		 * 第二个参数 : 形参类型
		 */
//		Method method = clazz.getMethod("dogSay", int.class);
		//调用方法
		/*
		 * 第一个参数 : 对象名
		 * 第二个参数 : 实参
		 */
//		method.invoke(dog, 10);
		
		System.out.println("--------------------调用私的方法---------------------------");
		
		//调用指定的方法 - 
		/*
		 * getDeclaredMethod(String name, Class<?>... parameterTypes) : 
		 * 		可以调用任意权限修饰符修饰的方法
		 * 第一个参数 : 方法名
		 * 第二个参数 : 形参的类型
		 */
		Method declaredMethod = clazz.getDeclaredMethod("dogInfo");
		//允许访问
		declaredMethod.setAccessible(true);
		//调用方法
		/*
		 * invoke(Object obj, Object... args) : 调用方法
		 * 第一个参数 : 对象名
		 * 第二个参数 : 实参
		 */
		declaredMethod.invoke(dog);
		
	}
	

	/*
	 * 通过反射获取属性
	 */
	@Test
	public void test(){
		//1.先获取Class对象
		Class clazz = Dog.class;
		//2.获取属性
		/*
		 * getFields() : 获取本类及父类中所public修饰的属性
		 */
		Field[] fields = clazz.getFields();
		//遍历
		for (int i = 0; i < fields.length; i++) {
			System.out.println(fields[i]);
		}
		
		System.out.println("--------------------------------------");
		
		/*
		 * getDeclaredFields() : 获取本类中所的属性
		 */
		Field[] declaredFields = clazz.getDeclaredFields();
		
		for (int i = 0; i < declaredFields.length; i++) {
			System.out.println(declaredFields[i]);
		}
	}
	
	/*
	 * 通过反射获取方法
	 */
	@Test
	public void test2(){
		//1.先获取Class对象
		Class clazz = Dog.class;
		//2.获取类中的方法
		/*
		 * getMethods() : 获取本类及父类中所public修饰的方法
		 */
		Method[] methods = clazz.getMethods();
		//遍历
		for (int i = 0; i < methods.length; i++) {
			System.out.println(methods[i]);
		}
		
		System.out.println("----------------------------------");
		
		/*
		 * getDeclaredMethods() : 获取本类中所的方法
		 */
		Method[] declaredMethods = clazz.getDeclaredMethods();
		for (int i = 0; i < declaredMethods.length; i++) {
			System.out.println(declaredMethods[i]);
		}
	}
	
	
	/*
	 * 通过反射获取父类
	 */
	@Test
	public void test5(){
		Class clazz = Dog.class;
		//获取父类 - 获取的是父类的类信息
		Class superclass = clazz.getSuperclass();
	}
	
	/*
	 * 通过反射获取注解
	 */
	@Test
	public void test6() throws Exception, Exception{
		Class clazz = Dog.class;
		//获取的是类上的注解
//		Annotation[] annotations = clazz.getAnnotations();
//		for (int i = 0; i < annotations.length; i++) {
//			System.out.println(annotations[i]);
//		}
		
		//获取属性上的注解 : ①先获取那个属性   ②再获取注解
		Field field = clazz.getField("dogAge");
		//获取属性上的注解
		Annotation[] annotations2 = field.getAnnotations();
		for (int i = 0; i < annotations2.length; i++) {
//			System.out.println(annotations2[i]);
			//如何获取注解上的那个值
			Annotation annotation = annotations2[i];
			
			MyAnn ma = (MyAnn) annotation;
			
			String s = ma.name();
			
			System.out.println(s);
		}
	}
	
	/*
	 * 通过反获取构造器 - 通过反射创建对象
	 */
	@Test
	public void test7() throws Exception, Exception{
		
		Class clazz = Dog.class;
		//获取指定构造器 - 获取的是空参构造器
//		Constructor constructor = clazz.getConstructor();
		//创建对象
//		constructor.newInstance();
		
		System.out.println("-----------------获取私带参构造器------------");
		
		/*
		 * 获取指定构造器 - 任意权限修饰符
		 * 
		 * getDeclaredConstructor(Class<?>... parameterTypes) : 方法形参是构造器形参的类型 
		 */
		Constructor constructor2 = clazz.getDeclaredConstructor(int.class);
		
		constructor2.setAccessible(true);
		/*
		 *  newInstance(Object ... initargs) : 方法的形参是往构造器中传的实参
		 */
		constructor2.newInstance(10);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值