zoukankan      html  css  js  c++  java
  • 【Java】反射机制

    反射

    反射:是底层技术 (开发工具和框架,使代码更通用)
    java.lang.reflect//反射包

    1).类对象Class

    是类加载的产物,封装了一个类的所有信息(类名,父类,接口,属性,方法,构造方法…)

    类加载: 当JVM第一次使用一个类的时候,需要读取这个类对应的字节码文件,获取类的信息并保存起来
    类对象: 记录类的信息的对象. 类加载后,将类的信息封装成类对象,保存在方法区中
    
    	获得类对象的三种方法:
    ①	Class c1 = HashMap.class; //获取类对象
    
    		②	Object o = new HashMap();
    			Class c2 = o.getClass();
    		
    		③	String className = “java.util.HashMap”; 	//写类的全名,带包
    			Class c3 = Class.forName(className); 		//Class.forName, 加载
    
    	常用方法:
    		getName()				 		获取全类名
    		getSimpleName() 					获取简单类名,不含包名
    		getSuperClass() 					获取父类的类对象
    		getInterfaces() 					获取所有实现了的接口类对象,返回Class[]
    		getField()							获取一个公开属性对象, 
    		getDeclaredField()	 				获取一个属性,包括非公开的
    		getFields()						获取所有的公开属性对象,包括继承自父类的属性
    		getDeclaredFields()	 				获取本类中所有的属性对象,
    		getMethod(“方法名”,参数表.class)		获取一个公开方法,注意参数表的位子
    		getDeclaredMethod(“方法名”,参数表.class)获取一个本类的方法,包括非公开的
    		getMethods() 					获取所有的公开方法,包括父类的
    getDeclaredMethods() 				获取本类所有的方法
    getConstructors() 					返回所有的构造方法的对象信息
    		
    	用法:例
    		Class c = HashMap.class;
    		System.out.println(c.getName());					//带包名,全名
    		System.out.println(c.getSimpleName());				//不带包名,简单名
    		System.out.println(c.getSuperclass().getName());	//父类的带包名
    		
    Class[] cc = c.getInterfaces();						//获得实现的接口
    		for(int i = 0; i < cc.length; i++) {				//遍历以实现的接口并打印名字
    			System.out.println(cc[i].getName());}
    

    2).Field

    Field:封装一个类对象的所有属性信息
    	常用方法:
    		getFields();返回类中所有的公开属性,包括父类中的属性,返回Field数组
    		getDeclaredFields();返回本类中所有属性,包括非公开属性,返回Field数组
    	用法:
    		class Student { public String name; public int age;}
    		main();
    			Class c = Student.class;
    			Field[] f = c.getFields();
    			for(int i = 0; i < f.length; i++) {
    				System.out.println(f[i]);
    			}
    

    3).Method

    Method:封装一个类对象的所有方法信息
    	常用方法:
    		getMethod(“方法名”, 此方法的参数表(例如Object.class));返回类中的一个方法,
    getDeclaredMethod(“方法名”, 此方法的参数表(例如Object.class)); 获取的一个包括非公开的方法
    		getMethods();返回类中所有的公开方法,包括父类中的方法,返回Method数组
    		getDeclaredMethods();返回本类中所有方法,包括非公开方法,返回Method数组
    
    	用法:
    	①  Class c = HashMap.class;
    		Method m1 = c.getMethod(“put”);//返回无参put方法
    		m1 = c.getMethod(“put”, Object.class, Object.class);//返回有两个Object类型参数的put方法
    System.out.println(m1.getReturnType().getName());//打印该方法的返回值类型名称
    
    	②  Method[] m2 = c.getMethods(); //返回类对象c内的所有公开方法,包括父类的方法
    		for(int i = 0; i < m2.length; i++) {
    			System.out.println(m2[i].getName());
    		}
    
    ③  Method[] m3 = c.getMethods(); //返回类对象c内的所有非公开方法
    		for(int i = 0; i < m3.length; i++) {
    			System.out.println(m3[i].getName());
    		}
    

    3).Constructor

    Constructor:封装一个类对象所有构造方法信息
    	常用方法:
    	getConstructos();返回类中所有的构造方法,包括父类中的方法,返回Constructor数组
    	
    	用法:
    		Class c = Student.class;
    		Constructor[] ct = c.getConstructors(); //获取所有构造方法
    		System.out.println(ct[0].getName());
    

    4).利用反射处理类的对象(实例化对象、调用方法)

    	动态对类做操作:
    		①对Class对象调用newInstance(),可以创建该类的对象调用无参构造方法
    			Class c = Class.forName(“com.baizhi.Student”); //注意抛异常
    			c.newInstance();
    		②对Method对象调用invoke(Object o),对o调用方法
    			Method m = 对象.getMethod(“方法名”,参数类型.class);
    			m.invoke(o);
    		③可以调用私有方法,但必须先将方法的可访问性属性改为true(setAccessible(true))
    			Method m = 对象.getDeclaredMethod(“方法名”,参数类型.class);//私有方法
    			m.setAccessible(true); //修改可访问性
    			m.invoke(o);
    		④访问并设置对象的属性
    
    	用法:
    		class Student { 
    			public void study() { System.out.pritln(“在学习”);}
    	public String study(String course) { return “学习课程:” + course; }
    }
    main():
    	//Student o = new Student();
    	Class c = Class.forName(“包.Student”);//加载类Student
    	Object o = c.newInstance();//创建类的对象
    
    	//o.study();调用无参方法
    	Method m1 = c.getDeclaredMethod(“study”); //获取无参的study方法
    	m1.invoke(o); //调用方法
    	
    	//o.study();调用有参方法
    	Method m2 = c.getDeclaredMethod(“study”, String.class); //获取方法
    	Object result = m2.invoke(o, “CoreJava”); //调用有参构造,并将返回值赋给o
    	System.out.println(result);
    
  • 相关阅读:
    需求分析作业01
    2016年秋季个人阅读计划
    个人总结
    梦断代码读后感03
    进度条16
    我的第一个小系统总结
    进度条15
    eclipse连接SqlServer2008(被它搞得惨兮兮)
    梦断代码读后感02
    Android ViewPager刷新解析
  • 原文地址:https://www.cnblogs.com/jwnming/p/13634606.html
Copyright © 2011-2022 走看看