反射

1. 什么是反射

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

标题: 一切反射相关的代码都从获得类对象开始

Class.forName(完整类名)
类名.class
对象.getClass()

2.实践操作

2.1 获取类对象的三种方式

package com.zking.zhoujun;

/**
 * 获取类对象的方式 Class.forName("")   xxx.class 对象.getClass
 * @author 周俊
 *
 */
public class Demo1 {
		public static void main(String[] args) throws Exception {
		//	Class clz = Class.forName("com.zking.zhoujun.Student");
			//Class clz=Student.class;
			Student stu=new Student();
			Class clz=stu.getClass();
			System.out.println(clz);
		}
}

2.2 反射实例化

package com.zking.zhoujun;

import java.lang.reflect.Constructor;

/**
	 * 反射实例化对象
	 * 1 无参共有的实例化
	 * 2 有一个参数的共有构造器实例化
	 * 3有两个参数的共有构造器实例化
	 * 4私有构造器实例化
	 * @author 周俊
	 *通用分页中的查询中使用
	 */
     public class Demo2 {
    	 public static void main(String[] args) throws Exception{
    		 //opp实例化对象
    		 Student stu=new Student();
 			Class<? extends Student> clz=stu.getClass();
 			//反射实例化
 			//1 无参共有的实例化
 			Student stu2 = (Student) clz.newInstance();
 			System.out.println(stu2);
 			
//为什么学习反射? 1能够让代码更具有灵活性
// 为什么在new关键字实例化对象后,需要学习反射实例化?			
// 1:能够将未知的对象进行实例化  
 			 /**
 			 * 2 有一个参数的共有构造器实例化
 			 * 3有两个参数的共有构造器实例化
 			 *4 私有构造器实例化
			 */
 			System.out.println("***************************************");
 			Constructor<? extends Student> c = clz.getConstructor(String.class);
 			Student stu3 = c.newInstance("s001");
 			System.out.println(stu3);
 			System.out.println("***************************************");
 			Constructor<? extends Student> c2 = clz.getConstructor(String.class,String.class);
 			Student stu4 = c2.newInstance("s001","张三");
 			System.out.println(stu4);
 			
 			System.out.println("***************************************");
//		java.lanf.NosuchMethodException:student类中没有Intefer为参数的构造方法	
// 		getConstructor是获取到public修饰的构造方法
// 		getDeclaredConstructor能够获取到任意修饰符的构造器
// 		java.lang.IllegalAccessException非法访问	
 		Constructor<? extends Student> c3 = clz.getDeclaredConstructor(Integer.class);
 		c3.setAccessible(true);
 		Student stu5=c3.newInstance(22);
 		System.out.println(stu5);
 		
		}
    		
}

输出结果:

反射_第1张图片
2.3 反射的调用方法

package com.zking.zhoujun;

import java.lang.reflect.Method;

/**
 * 反射实例化对象
 * 1 无参共有的方法调用化  2.有一个参数的方法调用 3.有两个参数方法调用 4私有的方法调用
 * @author 周俊
 *
 */
public class Demo3 {
	public static void main(String[] args) throws Exception{
		 Student stu=new Student();
		Class<? extends Student> clz=stu.getClass();
		
		Method m = clz.getMethod("hello");
		Object invoke = m.invoke(stu);
		//动态被调用的方法,如果该方法是void类型的返回值,那么被invoke 此时结果为null
		System.out.println(invoke);
		
		System.out.println("----------------------------------------");
		Method m2 = clz.getMethod("hello", String.class);
		Object invoke2 = m2.invoke(stu, "zhangsan");
		System.out.println(invoke2);
		
		Method m3 = clz.getDeclaredMethod("add", Integer.class,Integer.class);
		m3.setAccessible(true);
		Object invoke3 = m3.invoke(stu, 20,5);
		//动态调用方法,如果该方法是非void类型额返回值,那么被invoke后,就是该被调用方法的结果
		System.out.println(invoke3);
	}
}

输出结果:

反射_第2张图片
2.4 反射读写属性

package com.zking.zhoujun;

import java.lang.reflect.Field;

/**
 * 反射读写属性
 * BasaDao 增删改
 * @author 周俊
 *
 */
public class Demo4 {
		public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
			Student stu=new Student("s001","zhangsan");
			stu.age=22;
			Class<? extends Student> clz = stu.getClass();
			
			
			System.out.println(stu.getSname());
			Field f = clz.getDeclaredField("sname");
			f.setAccessible(true);
			System.out.println(f.get(stu));
			
			
			System.out.println("-----------------------------------");
			
	//反射读写属性常用方法(一次性获取该类的所有属性值)
	Field[] fs = clz.getDeclaredFields();
	for (Field ff:fs) {
		ff.setAccessible(true);
		System.out.println(ff.get(stu));
		
	}
	System.out.println("-----------------设置------------------");
	//想通过反射改变sname对应的值
	f.set(stu, "lisi");
	System.out.println(stu.getSname());
	
	
		}
}

输出结果:

反射_第3张图片

总结 :争取以后写出更好的博客

你可能感兴趣的:(java)