反射的运用

目录

一,什么是反射

二,类类

三,反射实例化

四,反射动态方法调用

五,反射读写属性


一,什么是反射

(1)反射java语言中的一种机制,通过这种机制可以动态的实例化对象,写属性,调用方法

(2)补充:框架:反射+设计模式组合而成的一个半成品(以下用制火药举例)
半成品就是  合成后的火药
反射+设计模式:合成后的火药 

二,类类

Class.forName(完整类名)

<代码演示>

		Class cls3 = Class.forName("com.dengxiyan.reflect.Student");

类名.class

<代码演示>

Class cls = Student.class;

对象.getClass

<代码演示>

Student stu = new Student();
		Class cls2 = stu.getClass();

《效果图》

三,反射实例化

(1)getConstructor

(2)getDeclaredConstructor

(3)newInstance

<代码演示>

package com.dengxiyan.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 有以下几种情况
 * 1.无参数 共有的构造方法
 * 2.有参数 共有的构造方法
 * 3.有多个参数 共有的构造方法
 * 4.私有的构造方法
 * @author DXY
 *2022年6月16日下午2:53:09
 */
public class Demo2 {

	public static void main(String[] args) throws Exception, IllegalAccessException {
		//调用无参的构造方法
		Student stu1 = new Student();
		//调用有参的构造方法
		Student stu2 = new Student("s001");
		//调用有多个参数的构造方法
		Student stu3 = new Student("s001","张三");
		
		
		System.out.println("--------------------------以下为反射的方式实例化对象-------------------------");
		//获取类类
		Class<? extends Student> cls1 = stu1.getClass();
		 //1.无参数 共有的构造方法
		System.out.println("--------------------------1.无参数 共有的构造方法-------------------------");
		Student stu4 = cls1.newInstance();
	
		/**
		 * 2.有参数 共有的构造方法
		 * (1)拿到构造器对象
		 */
		//(1)拿到构造器对象  三点代表乐意传多个参数  此处拿到的是一个String的构造器对象
		Constructor<? extends Student> c1 = cls1.getConstructor(String.class);
		System.out.println("--------------------------2.有参数 共有的构造方法-------------------------");
		Student stu5 = c1.newInstance("s001");
	
		//3.有多个参数 共有的构造方法 拿到两个参数的构造对象
		Constructor<? extends Student> c2 = cls1.getConstructor(String.class,String.class);
		System.out.println("--------------------------3.有多个参数 共有的构造方法-------------------------");
		Student stu6 = c2.newInstance("s001","李四");
		
		//4.私有的构造方法
		//getConstructor 只能够获取共有的构造方法 ,要获取私有的构造器就需调用getDeclaredConstructor
		Constructor<? extends Student> c3 = cls1.getDeclaredConstructor(Integer.class);
		//打开访问权限
		System.out.println("--------------------------4.私有的构造方法-------------------------");
		c3.setAccessible(true);
		Student stu7 = c3.newInstance(18);
	}
}

《代码效果图如下》

 

 

 

补充: (1)拿到构造器对象  三点代表乐意传多个参数 

 

 

 

(2) 以下标记代码默认就是调用无参   公有的  构造函数

<默认效果图如下>

 

 

 

《异常处理》 

异常原因:getConstructor 只能够获取共有的构造方法 ,要获取私有的构造器就需调用getDeclaredConstructor

 

 此处为什么还会抛异常 Class com.dengxiyan.reflect.Demo2 can not access a member of class com.dengxiyan.reflect.Student with modifiers "private"因为还没打开私有化访问权限

 

四,反射动态方法调用

(1)getMethod

(2)getDeclaredMethod

<代码演示>

package com.dengxiyan.reflect;

import java.lang.reflect.Method;

/**
 * 反射动态调用方法
 * 四种
 * 1.调用无参的共有方法
 * 2.调用1个有参的共有方法
 * 3.调用私有的方法
 * @author DXY
 *2022年6月16日下午3:36:05
 */
public class Demo3 {

	public static void main(String[] args) throws Exception{
		/**
		 * 步骤:
		 * 1.先拿到类类
		 * 2.拿到方法对象
		 * 3.调用对应的方法
		 */
		Class<Student> cls = Student.class;
		/**
		 * 1.调用无参的共有方法
		 */
		System.out.println("--------------------------1.调用无参的共有方法-------------------------");
		//name:被实例的方法名      parameterTypes:值得是方法对应的参数
		Method m1 = cls.getMethod("hello");
		//调用对应的方法
		//第一个参数:指的是类实例   第二个参数:方法调用时的实参
		//m1.invoke方法调用的返回值就是方法对象本身的返回值
		Object invoke = m1.invoke(cls.newInstance());
		System.out.println(invoke);
		
		/**
		 * 2.调用1个有参的共有方法
		 */
		System.out.println("--------------------------2.调用1个有参的共有方法-------------------------");
		Method m2 = cls.getMethod("hello", String.class);
		Object invoke2 = m2.invoke(cls.newInstance(), "张三");
		System.out.println(invoke2);
		
		
		
		/**
		 *  3.调用私有的方法
		 */
		System.out.println("--------------------------2.调用1个有参的共有方法-------------------------");
		Method m3 = cls.getDeclaredMethod("add", Integer.class,Integer.class);
		//打开访问权限
		m3.setAccessible(true);
		Object invoke3 = m3.invoke(cls.newInstance(), 5,5);
		System.out.println(invoke3);
	}
}

《效果图》

 分析效果图:

因为此方法返回类型是void,所以为空

 

 为什么为null,因为hello方法是无返回型的 

 

 

 

 

五,反射读写属性

(1)getDeclaredField

(2)getDeclaredFields

《代码演示》

错误代码分析:

        System.out.println("age: "+stu.age);
        System.out.println("sname: "+stu.getSname());
        System.out.println("sid: "+stu.getSid());

        
     
         以上代码存在的问题
         1.事先得知这个类的每个属性(对未知的东西没办法获取)
         2.假设Student有30个属性呢(代码量大)

package com.dengxiyan.reflect;

import java.lang.reflect.Field;

/**
 * 反射读写属性
 * @author DXY
 *2022年6月16日下午4:04:19
 */
public class Demo4 {

	public static void main(String[] args) throws Exception {
		//创建学生实例
		Student stu = new Student("s003","张三");
		stu.age = 20;
		//需求;拿到这个学生所有的学生及属性值

		
		//注意:一切反射从类类开始
		Class<? extends Student> cls = stu.getClass();
		//当前类的所有属性
		Field[] fields = cls.getDeclaredFields();
		System.out.println(fields.length);
		//f代表每一个属性对象
		for (Field f : fields) {
			//打开访问权限
			f.setAccessible(true);
			//通过属性对象拿到属性名称
			System.out.println(f.getName());
			//拿到当前属性对象的属性值
			System.out.println(f.get(stu));
			
		}
		
		
	}
}

《效果图》

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值