2020-09-23(反射)

package net.csdn.blog.wdd9527.week05.day03.test01;

//获取未知类里面的内容(没有提及的参考获取)

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo {
	
	public static void main(String[] args) {
		//test01();//拿对象
		//test02();//拿属性
		//test03();//拿构造方法
		test04();//拿方法
	}
	
	//拿对象
	public static void test01() {
		//方法1.使用对象.class(); 不推荐使用
		Worker w = new Worker();
		Class<? extends Worker> c1 = w.getClass();
		System.out.println(c1);
		//方法2.使用Class类的静态方法,forName();参数为类的全限定路径名, 推荐使用
		try {
			Class<?> c2 = 
                     Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
			System.out.println(c2);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//方法3.使用类的.class语法,不推荐使用
		Class<?> c3 = Worker.class;
		System.out.println(c3);
		
		//方法4.针对包装类,有一个TYPE语法,用的少,
		//Integer i = 22;
		Class<Integer> c4 = Integer.TYPE;
		System.out.println(c4);
	}
	
	//拿属性  一般不做拿属性的操作 了解了解把
	public static void test02() {
		try {
            //首先要拿到对象
			Class<?> c = 
             Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker"); 
			//.getFields()  拿到所有共有的方法
			Field[] fields = c.getFields();
			for (Field field : fields) {
                //.toString()与.toGenericString() 后者更详细,推荐用
				System.out.println(field.toGenericString()); 
			}
			
			//.getDeclaredFields()  拿到所有的方法
			Field[] declaredFields = c.getDeclaredFields();
			for (Field field : declaredFields) {
				System.out.println(field.toGenericString());
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	//拿构造方法
	public static void test03() {
		try {
			Class<?> c = 
                     Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker"); 
			//.getConstructors()  拿到所有共有的构造方法
			Constructor<?>[] constructors = c.getConstructors();
			for (Constructor<?> constructor : constructors) {
				System.out.println(constructor.toGenericString());
			}
			
			//.getDeclaredConstructors()  拿到所有构造方法
			Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
			for (Constructor<?> constructor : declaredConstructors) {
				System.out.println(constructor.toGenericString());
			}
			
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	//拿方法
	public static void test04() {
		try {
			Class<?> c = 
                     Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
			
			//.getMethods()  
            // 拿方法有点特殊,这个是拿到所有共有的方法(包括从父类继承来的方法,隐藏的方法)
			/*Method[] methods = c.getMethods();
			for (Method method : methods) {
				System.out.println(method.toGenericString());
			}
			*/
			//.getDeclaredMethods()  拿到本类的所有方法,包括私有的,仅限本类
			Method[] declaredMethods = c.getDeclaredMethods();
			for (Method method : declaredMethods) {
				System.out.println(method.toGenericString());
			}
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
package net.csdn.blog.wdd9527.week05.day03.test01;

import java.lang.reflect.Constructor;

//动态初始化对象

public class Demo02 {
	public static void main(String[] args) {
		//Worker w = new Worker(); 常用的初始化对象的方法
		try {
			/**
			 * 1.首先要获取要初始化的对象
			 * 2.然后用这个对象调用.newInstance()方法,初始化一个无参的对象。
			 */
			
			//无参构造方法初始化对象
			Class<?> c =                 
                    Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
			Object obj = c.newInstance();
			
			//初始化成功之后,也可以向下转型,然后对该对象类的内容进行相关操作
			if (obj instanceof Worker) { 
				Worker w = (Worker) obj;
				w.setName("王二麻子");
				w.setAge(22);
			}
			
			System.out.println(obj.toString());  //获取无参,即没有赋值,全是null
			
			/**
			 * 1.首先要获得要初始化的对象
			 * 2.然后这个对象调用.getConstructor(参数列表)方法,获得带参的构造方法
			 * 3.然后用这个带参的构造方法调用 .newInstance(参数列表),进行初始化对象 
			 * 注意:1.获取构造方法的时候,参数列表要和此类拥有的构造方法的参数列表相对应
			 *     2.用.getConstructor(参数列表)获取构造方法,参数列表要用:类型.class相对应
			 */
			
			//有参构造方法的初始化
			Class<?> c1 = 
                      Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
			//parameterTypes  参数类型/形参列表(包括类型和个数)
            //获取带参数的构造函数
			Constructor<?> constructor = c1.getConstructor(String.class);  
            //用获取的构造函数进行初始化
			Object newInstance = constructor.newInstance("张三");   
			
			//初始化成功之后,也可以向下转型,然后对该对象类的内容进行相关操作
			if (newInstance instanceof Worker) { 
				Worker w = (Worker) newInstance;
				w.setAge(18);
				w.setSalary(88);
				w.work();
			}
			
			System.out.println(newInstance);
			/**
			 * 使用Method的invoke方法执行方法,而不是通过对象(重点)
			 */
			
			//获得要初始化的对象
			Class<?> c2 =     
                      Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
			//获得要初始化的对象的构造函数
			Constructor<?> constructor2 = c2.getConstructor();
			//初始化对象
			Object newInstance2 = constructor2.newInstance();
			//获取这个对象所在类中将要用到的方法 参数为方法名和需要的形参
			Method method = c2.getMethod("setName", String.class);
			//用获得的这个方法调用.invoke() 传入要操作的对象和这个方法需要的形参 
			Object invoke = method.invoke(newInstance2, "李四");
			
			Method method2 = c2.getMethod("setAge", Integer.class);
			method2.invoke(newInstance2, 33);
			
			System.out.println(newInstance2.toString());
			System.out.println(method);
			System.out.println(invoke);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



输出结果:
Worker [name=王二麻子, age=22, salary=null]
张三正在努力干活....
Worker [name=张三, age=18, salary=88]
Worker [name=李四, age=33, salary=null]
public void net.csdn.blog.wdd9527.week05.day03.test01.Worker.setName(java.lang.String)
null

package net.csdn.blog.wdd9527.week05.day03.test01;

//不论类在哪里,只要路径对了就可以(同一个项目下)

import java.lang.reflect.Constructor;

import net.csdn.blog.wdd9527.week01.day01.Teacher;


public class Demo03 {
	public static void main(String[] args) {
		try {
			Class<?> c = Class.forName("net.csdn.blog.wdd9527.week01.day01.Teacher");
			Constructor<?>[] constructors = c.getConstructors();
			Constructor<?> constructor2 = c.getConstructor();
			
			Object obj = constructor2.newInstance();
			
			if (obj instanceof Teacher) {
				Teacher t = (Teacher) obj;
				t.setName("苍老师");
			}
			
			System.out.println(obj);
			
			for (Constructor<?> constructor : constructors) {
				System.out.println(constructor);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

输出结果:
Teacher [name=苍老师, course=null]
public net.csdn.blog.wdd9527.week01.day01.Teacher(java.lang.String,java.lang.String)
public net.csdn.blog.wdd9527.week01.day01.Teacher()

package net.csdn.blog.wdd9527.week05.day03.test02;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		/**
		 * 1.创建两个map集合,分别保存Student和Worker的信息
		 * 2.把信息分别赋值给Student和Worker对象
		 * 3.把第二步抽象成一个方法(不然再添加呢?)
		 */
		HashMap<Object, Object> map1 = new HashMap<>();
		map1.put("name", "张三");
		map1.put("age", 22);
		map1.put("sex", '男');
		map1.put("grade", 5);
		System.out.println(map1);
		
		HashMap<Object, Object> map2 = new HashMap<>();
		map2.put("name", "李四");
		map2.put("age", 21);
		map2.put("salary", 9999);
		System.out.println(map2);
		
		//map1的
		/*Student s = new Student();
		System.out.println(s.getClass());*/
		try {
			Object setObj = setObj(map1,         
"net.csdn.blog.wdd9527.week05.day03.test02.Student");
			System.out.println(setObj);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//map2的
		/*Worker s1 = new Worker();
		System.out.println(s1.getClass());*/
		try {
			Object setObj2 = 
setObj(map2,"net.csdn.blog.wdd9527.week05.day03.test02.Worker");
 			System.out.println(setObj2);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		/*Student s = new Student();
		s.setName((String)map1.get("name"));
		s.setAge((int)map1.get("age"));
		s.setSex((char)map1.get("sex"));
		s.setGrade((Integer)map1.get("grade"));
		System.out.println(s.toString());
		
		Worker s1 = new Worker();
		s1.setName((String)map2.get("name"));
		s1.setAge((int)map2.get("age"));
		s1.setSalary((int)map2.get("salary"));
		System.out.println(s1.toString());*/
	 
	}
	
	
	public static Object setObj(HashMap<Object, Object> map,String className) throws Exception {
		Class<?> forName = Class.forName(className); //获取形参所代表类的对象
		Object newInstance = forName.newInstance();  //初始化这个对象
		Method[] methods = forName.getMethods();  //获取类中的所有方法,待会筛选出需要的set方法   
		Set<Object> keySet = map.keySet();       //遍历键,从而得到需要的值,达到对象的初始化
		
		/**
		 * 分别要循环形参所代表类的所有方法和形参传来的map集合的键,
		 * 从而获得所需要的set方法和键所对应的值,
		 * 从而达到对象的初始化
		 * setName-->name
		 * setAge-->age
		 * setSex-->sex
		 * setGrade-->grade
		 */
		for (Object key : keySet) {
			if (key instanceof String) {   //讲key值转换为String类型,方便比较
				String k = (String) key;
				for (Method m : methods) {
					//只需要setXXX的方法,所以首先筛选出以set开头的方法,然后再判断键
					if (m.getName().startsWith("set") && k.equalsIgnoreCase(m.getName().substring(3))) {
						m.invoke(newInstance, map.get(k));  //方法.invoke(对象,方法所对应的形参)
					}
				}
			}
			//System.out.println(key + " " + map.get(key));
		}
		return newInstance;
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值