Java反射

1.什么是反射?
    反射是一门动态的创建对象的技术
    反射可以在运行期期间  动态的 访问和操作对象的 属性 和 方法
2.为什么要有反射?
    java 是一门静态的语言
    因为有了反射  java被称为 半动态语言
    
    java有一个致命的缺陷 : 所有的对象 都是预先定义好的
                     即 : 在编程期间定义好了 对象的创建  并不能根据实际运                           行期需求来创建
3.反射的作用?

    动态的创建对象        动态的 访问和操作对象的 属性 和 方法

4.类也是对象

    Class类

        1. 地址

        2. 名字

        3. 属性类对象
        4. 构造器类对象
        5. 方法

        该对象是  Class 类的对象  , 存储的东西  是 本类的信息
        Class 类的对象 总是对应着 一个类信息 。

        Class 类的对象 被称之 类对象

5.使用反射来操作  
1. 使用反射来获取和操作 属性
2. 使用反射来获取和操作方法

3. 使用反射来获取和操作构造器




3种方法或得类对象:

*****************************************************

		
                
              Student student = new Student();
                // 1.根据类获得类对象 
		clazz = Student.class;
		
		// 2.根据本类的对象获得 本类的 类对象
		Class clazz2 = student.getClass();
		
		// 3.根据类的地址 获得 本类的 类对象   最主要 用的最多的
		Class clazz3 = Class.forName("com.hainiu.use.Person");

使用反射 获取和操作构造器

*****************************************************

/**
		 *  使用反射 获取和操作构造器
		 * @throws ClassNotFoundException 
		 * @throws SecurityException 
		 * @throws NoSuchMethodException 
		 * @throws InvocationTargetException 
		 * @throws IllegalArgumentException 
		 * @throws IllegalAccessException 
		 * @throws InstantiationException 
		 */
		private static void useConstructor() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
			Class clazz = Class.forName("com.hainiu.use.Student");
			// 获取构造器
				System.out.println("==========获取所有的公共的构造器==========");
				// 获得本类所有的公共的构造器   没有父类的
				Constructor[] constructors = clazz.getConstructors();
				for (Constructor constructor : constructors) {
					System.out.println(constructor);
				}
				System.out.println("==========获取所有的声明的构造器==========");
				// 获得本类声明的所有构造器
				constructors = clazz.getDeclaredConstructors();
				for (Constructor constructor : constructors) {
					System.out.println(constructor);
				}
				
				
				
				System.out.println("==========获取唯一的公共的构造器==========");
				Constructor constructor = clazz.getConstructor(String.class,int.class);
				System.out.println(constructor);
				System.out.println("==========获取唯一的声明的构造器==========");
				constructor = clazz.getDeclaredConstructor(String.class);
				System.out.println(constructor);
			
				/**
				 * 基本操作
				 */
				System.out.println("*****"+constructor.getModifiers());	//获取修饰符
				System.out.println(constructor.getName());
				System.out.println(constructor.getParameterCount());	//获取形参数目
				System.out.println(constructor.getParameterTypes());	//获取形参类型
				
				System.out.println("===========操作构造器============");
			
			// 操作构造器
				// 它的操作最简单 也最重要
				//使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
				Object newInstance = constructor.newInstance("哈哈哈");
				System.out.println(newInstance);
				
				
				// 单例
				Class mathClass = Math.class;
				@SuppressWarnings("unchecked")
				Constructor con = mathClass.getDeclaredConstructor();
				con.setAccessible(true);
				Object ooo = con.newInstance();
				Math math = (Math)ooo;
				System.out.println(math.hashCode());
				System.out.println(math);
		}

获取和操作方法

/**
	 *  使用反射获取和操作   方法 
	 * @throws ClassNotFoundException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void useMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
		Class clazz = Class.forName("com.hainiu.use.Student");
		// 获取 方法对象  4种
			// 1. 获取所有的公共的方法   包括父类的 
			Method[] methods = clazz.getMethods();
			for (Method method : methods) {
//				System.out.println(method);
			}
			System.out.println("============获取所有的 本类声明的方法========");
			// 2. 获取所有的 本类声明的方法   不包括    想获得父类的 先获得父类的类对象
			methods = clazz.getDeclaredMethods();
			for (Method method : methods) {
//				System.out.println(method);
			}
			System.out.println("============获取单个的 公共的方法========");
			// 3. 获得单个的 公共的方法
			Method method = clazz.getMethod("show",int.class);
			// parameter->参数  types->类型	Class... parameterTypes
			// Class [] c = {int.class,int.class};
			// 有几个参数  就给几个 参数类型.class  没有就只给名字就可以
			System.out.println(method);
			System.out.println("============获取单个的声明的方法========");
			// 4. 获得单个的 声明的方法
			method = clazz.getDeclaredMethod("setSage", int.class);
			System.out.println(method);
		
			
			/**
			 * 以上是 获取方法对象的 4种方式
			 * 以下是 方法对象的简单操作
			 */
			
			
			System.out.println(method.getName());
			System.out.println(method.getModifiers());
			System.out.println(method.getReturnType());// 返回值类型
			System.out.println(method.getParameterCount());// 参数个数
			Class<?>[] parameterTypes = method.getParameterTypes();// 参数类型
			for (Class<?> class1 : parameterTypes) {
				System.out.println(class1);
			}
			
		
		
		// 操作 方法对象
		/**
		 * 操作方法对象   方法有静态和非静态
		 * 静态从属类  非静态从属对象
		 */
			// 操作静态方法
			method = clazz.getDeclaredMethod("show");
			// 执行方法 必须给参数  不管方法有没有返回值 这里接收一个返回值  如果原方法没返回  那么返回null
			Object obj = method.invoke(null);// 静态方法依附于类  所以参数1 给null
			System.out.println(obj);
			
			// 	操作非静态方法  从属于对象
			method = clazz.getDeclaredMethod("add",int.class,double.class);
			Student stu = (Student) clazz.newInstance();
			Student student = new Student();
			Object invoke = method.invoke(stu,3,1.1);
			method.invoke(student,3,1.1);
			System.out.println(invoke);
			
			
			System.out.println("============使用反射检测泛型运行期被擦除==============");
			
			List<String> list = new ArrayList<>();
			list.add("你不让我加stu");
			list.add("我偏要加");
			list.add("我要这天再也遮不住你的脸");
			
			Class cl = list.getClass();
			Method m = cl.getDeclaredMethod("add", Object.class);
			m.invoke(list, stu);
			
			for(Object o : list)
				System.out.println(o);
			
			
			System.out.println("---------");
			
			for (String string : list) {
				System.out.println(string);
			}
	}
	

操作属性

/**
	 * 使用反射 获取 和 操作    对象的属性
	 * @throws ClassNotFoundException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws InstantiationException 
	 */
	public static void useField() throws ClassNotFoundException, 
	NoSuchFieldException, SecurityException, IllegalArgumentException,
	IllegalAccessException, InstantiationException{
		
		Class clazz = Class.forName("com.hainiu.use.Student");
		// 获取属性 对应的对象    4种方式  各有千秋		
			// 获取所有的公共的属性	所对应的对象	包含父类的
			Field[] fields = clazz.getFields();
			for (Field field : fields) {
				System.out.println(field);
			}
			System.out.println("===========获取本类声明的所有的属性对象==========");
			// 获取所有本类声明的属性 
			Field[] declaredFields = clazz.getDeclaredFields();
			for (Field field : declaredFields) {
				System.out.println(field);
			} 
			// 如何获得父类声明的  属性对象呢  ?   先获得父类的类对象   然后用相同的方式
			
			System.out.println("===========获取本类公共的单个的属性对象==========");
			// 获得单个公共的属性对象
			Field field = clazz.getField("name");
			System.out.println(field);
			System.out.println("===========获取本类公共的单个的属性对象==========");
			// 获取单个本类声明的属性对象
			field = clazz.getDeclaredField("sscore");
			System.out.println(field);
			
			/**
			 * 以上是获得 属性对象 四种方式 
			 * 以下是 或得到属性对象的 基本操作
			 */
		
			System.out.println("===========基操==========");
			System.out.println(field.getName());
			System.out.println(field.getModifiers());
			System.out.println(field.getType());
			System.out.println("============获取操作静态属性=========");
			/**
			 *  以下是操作属性
			 *  属性有静态 和 非静态 之分
			 *  静态的属性从属于类
			 *  非静态属性从属对象
			 */
			// 获取到属性  然后操作属性
				// 操作静态属性
				field = clazz.getDeclaredField("id");
				// get方法是获取值得方法  因为静态属性从属于类   所以此时不需要给对象 直接给null
				Object obj = field.get(null);
				System.out.println(obj);
				// set方法是修改值得方法 静态属性第一个参数给null  第二个参数给 值
				field.set(null, 123);
				obj = field.get(null);
				System.out.println(obj);
			
				// 操作非静态属性
				// 操作非静态的属性 必须有对象才行 没有对象意味着 属性不存在
				Student stu = (Student) clazz.newInstance();
				Student student = new Student("张三",18,true,99);
				System.out.println(stu);
				field = clazz.getDeclaredField("sname");
				// 此时必须指明对象 
				obj = field.get(student);
				System.out.println(obj);
				
				field.set(stu, "李四");
				field.set(student, "不叫zhangsan");
				System.out.println(stu);
				System.out.println(student);
				
				
				System.out.println("============暴力反射=================");
				/**
				 *  暴力反射
				 */
				field = clazz.getDeclaredField("sscore");
				System.out.println(field);
				
				// 暴力反射  忽略权限的限制   方法来源父类
				field.setAccessible(true);
				
				System.out.println(field.get(student));
				System.out.println(field.get(stu));
				
				field.set(stu, 180);
				field.set(student, 180);
				
				System.out.println(field.get(student));
				System.out.println(field.get(stu));
				
				
				System.out.println(" ============  再次  测试 暴力反射  ==============");
				field = clazz.getDeclaredField("i");
				field.setAccessible(true);
				field.set(stu, 3333);
				System.out.println(field.get(stu));// 反射获取属性值
				System.out.println(stu);// 正常去输出 属性值
				
	}

    









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值