反射

风流意气都作罢 提交于 2020-02-17 09:34:18

概念

反射:将类的各个组成部分封装成其他对象
java代码在计算机中经历的阶段

  • 首先书写Java代码,然后Java代码通过编译称为字节码文件(类名.class)存储在硬盘中(disk)。
  • 然后,将硬盘中的字节码加载进内存。
    Java中有一个Class类,用来描述字节码文件。类似下面,将成员变量,构造函数和方法分别封装成数组。
public class Class {
public Field [];//成员变量
public Construct [];//构造函数
publid Method [];//方法
}
  • 最后,new 一个对象使用。

反射的优点

  • 可以在代码执行过程中调用
    例如编译器中的方法提示功能。可以将相关的方法放在Method数组中,使用时打印
  • 解耦
    class字节码文件

代码

1、获取Class
2、Field:设置和获得值
3、Construct
4、Method

Person类

public class Person {
	 public String age;
	 private String name;
	 
	 public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	 }

1、获取Class

          	public static Class getPersonClass() {
		 //1、通过对象.getclass
			Person p=new Person();
		    Class pClass=p.getClass();
		   //2、通过class
			lass pClass=Person.class;
			return pClass;
	 }

2、获取和设置变量的值

		Field[] f=pClass.getFields();//将所有的成员变量(public型的)存到Field类的数组中
		for(int i=0;i<f.length;i++)
		 System.out.println(f[i]);//打印所有变量对象
			
			
		Field age=pClass.getField("age");//将age变量转化成Field类型
		System.out.println(age);//打印age
			
			
		//获取值
		Object o=age.get(p);//获得p对象中age的值。	get(Object obj)返回该所表示的字段的值 Field ,指定的对象上。  
		System.out.println(o);
		//设置值
		age.set(p, "aa");//将p对象的age的值设置为"aa"
			
		Object o1=age.get(p);
		System.out.println(o1);
		//getDeclaredFields()将所有的属性名封装成Field对象数组,不论是什么权限
			Field[] f2=pClass.getDeclaredFields();
			for(int i=0;i<f2.length;i++)
			System.out.println(f2[i]);

			//getDeclaredField(String 属性名)将某一个属性封装成Field对象
 			Field f3=pClass.getDeclaredField("name");
			System.out.println(f3);

			//获取值
			System.out.println(f3.get(p));
			System.out.println("---------------------------");
			//设置私有属性的属性值
			f3.setAccessible(true);//暴力反射,会忽略安全修饰符的检查
			f3.set(p,"mm");
			System.out.printpclass.getConstructors()ln(f3.get(p));

3、获取构造函数Construct

  • 获取所有的构造方法 pclass.getConstructors()
 public static void getPersonConstruct()
	 {
		 Class pclass=getPersonClass();
		 Constructor [] cons1=pclass.getConstructors();
		 for(int i=0;i<cons1.length;i++)
		 {
			 System.out.println(cons1[i]);
		 }
	 }
  • 获取特定的构造方法:使用pclass.getConstructor();参数是对应数据类型的class对象,可为空。
  public static void getPersonConstruct1() throws Exception, SecurityException
	 {
		 Class pclass=getPersonClass();
		 Constructor cons1=pclass.getConstructor(String.class,String.class);
		 System.out.println(cons1);
	 }
  • 创建对象:如果是空构造函数。使用class.newInstance()或者cons1.newInstance();否则,使用cons1.newInstance(参数),注意,参数是对象类型的可变参数
 public static void getPersonObject() throws Exception, SecurityException
	 {
		 Class pclass=getPersonClass();
		 Constructor cons1=pclass.getConstructor(String.class,String.class);
		 Object o=cons1.newInstance("张三","十三");
		 System.out.println(o);
		 System.out.println("如果构造空构造函数,可以使用class");
		 System.out.println(pclass.newInstance());
	 }

获取方法

  • 获取所有公有方法:getMethod()和getMethod(“方法名”,数据类型类对象)
 public static void getPersonMethod() throws NoSuchMethodException, SecurityException
	 {
		 Class pclass=getPersonClass();
		 //获取所有的公共方法
		 Method[] methods = pclass.getMethods();
		 for(int i=0;i<methods.length;i++)
		 {
			 System.out.println(methods[i]);
			 
		 }
		 System.out.println("----------------------");
		 //获取指定函数名和参数类型的方法
		 Method method=pclass.getMethod("eat1",String.class);
		 System.out.println(method);
		 //获取全部的方法
		//getDeclaredMethods()
		 //getDeclaringClass()
		
	 }
  • 获取所有方法:类似Field
  • 执行方法:invork(对象,可变参数的实参)
 public static void executePersonMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	 {
		 Class pclass=getPersonClass();
		 Method method=pclass.getMethod("eat1",String.class);
		 Person p=new Person();
		 method.invoke(p, "馒头");
		 
		 
	 }

获取类名
getName()

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!