java反射机制代码

今天,自己特意复习了一下java的反射机制,对一个类中的属性、方法及构造方法通过反射机制进行操作,关于反射机制的一些概念就不多说了,大家可以看我以前的java基础博客进行了解,下面的都是一些代码:

定义要操作的类(Person)及它的一个父类(Parent),然后在其里面定义了一些方法和属性:

Person类:

package com.xin.test;

public class Person extends Parent{
	private int personId;
	public String personName;
	
	public Person(){
		
	}
	
	public Person(String personName){
		this.parentName=personName;
	}
	
	private Person(int personId){
		this.personId=personId;
	}
	
	private int mul(int a,int b){
		return a*b;
	}
	
	protected int del(int a,int b){
		return a/b;
	}
	
	public int add(int a,int b){
		return a+b;
	}
}


Parent类:

package com.xin.test;

public class Parent {
	private int parentId;
	public String parentName;
	
	public Parent(){
		
	}
	public Parent(String parentName){
		this.parentName=parentName;
	}
	
	public void sayHello(){
		System.out.println("hello world");
	}

}

下面我们定义一个反射操作类ReflectTest来操作Person中的一些属性和方法:

1、获得Person字节码的三种方式,根据自己应用的场景选择相应的方式:

	//获得字节码的几种方式,得到信息:class com.xin.test.Person
	public Class<?> getClazz()throws Exception{
		//第一种方式
		Class<?> clazz=Class.forName("com.xin.test.Person");
		//第二种方式
		clazz=Person.class;
		//第三种方式
		Person p=new Person();
		clazz=p.getClass();
		return clazz;
	}

2、利用反射机制实例化对象:

	//利用反射机制实例化对象
	public void getObject()throws Exception{
		Class<?> clazz=Class.forName("com.xin.test.Person");
		System.out.println("-------使用下面方法实例化对象,必须提供无参数构造方法--------------");
		Person person=(Person)clazz.newInstance();
		person.sayHello();
		System.out.println("---------实例化有参数构造方法,先获得所有构造方法,再进行实例化-----------");
		Constructor<?>[] cons=clazz.getConstructors();
		person=(Person)cons[0].newInstance();
		person.sayHello();
	}


3、利用反射机制操作属性:

	//利用反射机制操作属性
	public void operateField()throws Exception{
		Class<?> clazz=Class.forName("com.xin.test.Person");//获得字节码信息
		//访问特定的属性,只能获取public访问修饰的属性信息:public int com.xin.test.Person.age
		System.out.println("-------得到类中特定的属性,该属性只能是public的---------");
		Field field=clazz.getField("personName");
		System.out.println(field);
		System.out.println("-------得到自身和父类的所有属性,属性只能是public的---------");
		//访问自身和父类的所有属性
		Field[] fields=clazz.getFields();
		for(Field field2:fields){
			System.out.println(field2);
		}
		
		System.out.println("-------得到自身类中一切访问修饰符的特定属性--------");
		//可以获取一切访问修饰的属性信息,包括private修饰符修饰的属性
		field=clazz.getDeclaredField("personId");
		System.out.println(field);
		//要操作private属性,需要给其添加下面的权限
		field.setAccessible(true);
		Person p=(Person)clazz.newInstance();//创建Person的一个实例对象,调用无参数构造函数
		System.out.println("----------给属性赋值和取值------------");
		field.setInt(p, 23);//给属性赋值  
		System.out.println(field.getInt(p));//取得相应属性的值
		System.out.println(field.getClass());//获得属性字节码文件
		
		System.out.println("------得到自身类中一切访问修饰符的所有属性---------");
		fields=clazz.getDeclaredFields();
		for(Field field2:fields){
			System.out.println(field2);
		}
		
		System.out.println("----------取得属性访问修饰符------------------");
		System.out.println(Modifier.toString(field.getModifiers()));
	}


4、利用反射机制操作构造方法:

	//利用反射机制操作构造方法
	public void operateConstructor()throws Exception{
		Class<?> clazz=Class.forName("com.xin.test.Person");//获得字节码信息
		System.out.println("------调用自身无参public构造方法----------");
		Constructor<?> con=clazz.getConstructor();
		System.out.println(con);
		System.out.println("------调用自身有参public构造方法----------");
		con=clazz.getConstructor(String.class);
		System.out.println(con);
		System.out.println("----------调用自身任何访问修饰符构造方法--------------");
		con=clazz.getDeclaredConstructor(int.class);
		System.out.println(con);
		System.out.println("----------调用自身所有的public构造方法--------------");
		Constructor[] cons=clazz.getConstructors();
		for(Constructor con2:cons){
			System.out.println(con2);
		}
		System.out.println("----------调用自身所有的任意修饰符修饰的构造方法--------------");
		cons=clazz.getDeclaredConstructors();
		for(Constructor con2:cons){
			System.out.println(con2);
		}
		System.out.println("---------利用构造方法实例化对象-------------");
		cons=clazz.getConstructors();
		Person p1=(Person)cons[0].newInstance();
		System.out.println("实例化无参数构造方法:"+p1);
		p1=(Person)cons[1].newInstance("Mary");
		System.out.println("实例化有参数构造方法:"+p1);
	}


5、利用反射机制操作方法:

	//利用反射机制操作方法
	public void operateMethod()throws Exception{
		Class<?> clazz=Class.forName("com.xin.test.Person");//获得字节码信息
		System.out.println("--------获得自身类中所有的方法-----------");
		//获得自身类中所有的方法,private方法也可获取到,打印输出private int com.xin.test.Person.mul(int,int)
		Method[] methods=clazz.getDeclaredMethods();
		for(Method method:methods){
			System.out.println(method);
		}
		System.out.println("--------获得自身类以及父类的所有的public方法,包括Object类-----------");
		//获得自身类public以及父类的public方法,还包括Object类
		Method[] methods2=clazz.getMethods();
		for(Method method:methods2){
			System.out.println(method);
		}
		System.out.println("---------获得自身类public修饰的特定方法-----------");
		Method method=clazz.getMethod("add", int.class,int.class);//获得add方法,add方法的访问修饰符需为public
		System.out.println(method.getModifiers()+"---"+method.getName()+"---"+method.getDefaultValue());
		System.out.println(method.invoke(clazz.newInstance(), 3,4));//执行方法
		
		System.out.println("---------获得自身类任意访问修饰符修饰的特定方法--------");
		Method method2=clazz.getDeclaredMethod("mul", int.class,int.class);//获得mul方法,mul方法访问修饰符可以为任意修饰符,包括private
		System.out.println(method2.getModifiers()+"---"+method2.getName()+"---"+method2.getDefaultValue());
		System.out.println("访问修饰符为"+Modifier.toString(method2.getModifiers()));
		method2.setAccessible(true);//如果方法的访问修饰符为private,需要加上这个,否则调用invoke方法会报错
		System.out.println(method2.invoke(clazz.newInstance(), 3,4));//执行方法
		
		System.out.println("---------获得方法参数类型---------");
		//获得方法mul中的参数类型
		Type[] types=method2.getGenericParameterTypes();
		for(Type type:types){
			System.out.println("方法中的参数类型为:"+type);
		}
		
		System.out.println("---------获得方法返回值类型-----------");
		//获得方法mul中的返回值类型
		System.out.println("方法返回值类型为:"+method2.getGenericReturnType());
	}
	


6、利用反射机制操作父类信息:

	//使用反射操作父类信息
	public void operateParent()throws Exception{
		Class<?> clazz=Class.forName("com.xin.test.Person");//获得字节码信息
		System.out.println("-----获得父类字节码-------------");
		clazz=clazz.getSuperclass();
		System.out.println(clazz);
		System.out.println("-----获得父类构造函数信息-------------");
		Constructor<?>[] cons=clazz.getConstructors();
		for(Constructor<?> con:cons){
			System.out.println(con);
		}
	}


其实利用反射机制还可以获取很多信息,例如接口类、注解信息等,没有一一列出,大家可以自己去尝试一下,我在测试这些类的时候,其实有一个疑问,就是clazz.getFields()、clazz.getMethods()可以获取父类中定义的public属性和方法,为什么clazz.getConstructors()却获取不到父类的构造方法呢,可能跟java机制有关吧,因为先要有父亲才会有儿子,这也是个人猜测;

在操作私有的属性和方法的时候,记得要给它们添加访问权限:setAccessible(true);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值