浅谈反射

在这里插入图片描述

@Test
public void testMethod1(){
	//传统做法,在编译期间确定调用的关系
	User user=new User();
	user.setUserName("张三");
	user.setUserPassword("zs");
	System.out.println(user.getUserName()+"   "+user.getUserPassword());
}
//反射的做法,首要要得到Class类型的对象,
//此对象,在类加载后自动由jvm创建,并把对象放在堆中
//程序员只是通过api获取Class对象
@Test
public void testMethod2()throws Exception{
	//方式一
	User user=new User();
	Class clazz1=user.getClass();
	//方式二
	Class clazz2=User.class;
	//方式三
	Class clazz3=Class.forName("User");
	
	//输出hashcode,hashcode值一样,证明此Class的对象只有一个
	System.out.println(clazz1.hashCode());
	System.out.println(clazz2.hashCode());
	System.out.println(clazz3.hashCode());
	System.out.println(ArrayList.class.hashCode());
}
/**
 * 用Class对象获取类中的
 * 所有的Field
 * 所有的Method
 * 所有的Constructor
 * 所有的Annotation
 * @throws Exception
 */
@Test
public void testMethod3()throws Exception{
	
	Class clazz=Class.forName(".User");
	
	Field[] fields=clazz.getDeclaredFields();
	Method[] methods=clazz.getDeclaredMethods();
	Constructor[] constructors=clazz.getConstructors();
	Annotation[] annotations=clazz.getDeclaredAnnotations();

}
/**
 * 从Class对象中获取Field
 * 当前类以及长辈类中的公有的属性
 * @throws Exception
 */
@Test
public void testMethod4_1()throws Exception{
	Class clazz=Class.forName("User");
	Field[] fields=clazz.getFields();
	for(Field field :fields){
		System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
		System.out.print(field.getType()+"   ");
		System.out.println(field.getName());
	}
}
/**
 * 从Class对象中获取Field
 * 当前类中的所有的属性
 */
@Test
public void testMethod4_2(){
	try {
		Class clazz=Class.forName("User");
		Field[] fields=clazz.getDeclaredFields();
		for(Field field :fields){
			System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
			System.out.print(field.getType()+"   ");
			System.out.println(field.getName());
		}
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class对象中获取Field
 * 当前类以及长辈类中的指定的公有的属性
 * @throws Exception
 */
@Test
public void testMethod4_3(){
	try {
		Class clazz=Class.forName("User");
		Field field=clazz.getField("desc1");
		
		System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
		System.out.print(field.getType()+"   ");
		System.out.println(field.getName());
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (NoSuchFieldException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
}
/**
 * 从Class对象中获取Field
 * 当前类中的指定的属性
 */
@Test
public void testMethod4_4(){
	try {
		Class clazz=Class.forName("User");
		Field field=clazz.getDeclaredField("userName");
		
		System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
		System.out.print(field.getType()+"   ");
		System.out.println(field.getName());
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class对象中获取Field
 * 要给Field存值
 */
@Test
public void testMethod4_5(){
	try {
		Class clazz=Class.forName("User");
		Field field=clazz.getDeclaredField("userName");
		
		System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
		System.out.print(field.getType()+"   ");
		System.out.println(field.getName());
		
		//创建对象
		Object obj=clazz.newInstance();
		//设置Field的可访问性
		field.setAccessible(true);
		//给Field存储数据
		field.set(obj, "zhangsan");
		if(obj instanceof User){
			User user=(User)obj;
			System.out.println(user.getUserName());
		}
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class对象中获取Field
 * 要从Field存值并取值
 */
@Test
public void testMethod4_6(){
	try {
		Class clazz=Class.forName("User");
		Field field=clazz.getDeclaredField("userName");
		
		System.out.print(field.getModifiers()+"  ");//int不同的值代表不同的访问修饰符
		System.out.print(field.getType()+"   ");
		System.out.println(field.getName());
		
		//创建对象
		Object obj=clazz.newInstance();
		//设置Field的可访问性
		field.setAccessible(true);
		//给Field存储数据
		field.set(obj, "zhangsan");
		//从Field中的取出数据
		Object value=field.get(obj);
		System.out.println(value);
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 创建对象
 * 方式一:调用的无参数构造实例化对象
 */
@Test
public void testMethod5_1(){
	try {
		Class clazz=Class.forName("User");
		
		Object obj=clazz.newInstance();
		System.out.println(obj.getClass());
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 创建对象
 * 方式二:调用的有参数构造实例化对象
 */
@Test
public void testMethod5_2(){
	try {
		Class clazz=Class.forName("User");
		
		//获取构造函数
		Constructor constructor=clazz.getConstructor(String.class,String.class);
		//Constructor constructor=clazz.getConstructor(new Class[]{String.class,String.class});
		Object obj=constructor.newInstance("张三","zs");
		Field field1=clazz.getDeclaredField("userName");
		Field field2=clazz.getDeclaredField("userPassword");
		field1.setAccessible(true);
		field2.setAccessible(true);
		System.out.println("userName="+field1.get(obj));
		System.out.println("userPassword="+field2.get(obj));
		System.out.println(obj.getClass());
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class中取出Method方法
 * 从当前代类及其长辈类中的所有的公有方法
 */
@Test
public void testMethod6_1(){
	try {
		Class clazz=Class.forName("User");
		
		Method[] methods=clazz.getMethods();
		for(Method method: methods){
			System.out.print(method.getModifiers()+"  ");//获取访问修饰符
			System.out.print(method.getReturnType()+"  ");//获取返回类型
			System.out.print(method.getName()+"(");//获取方法名称
			//获取参数列表
			Class[] claxxs=method.getParameterTypes();
			if(claxxs!=null && claxxs.length>0){
				for(int i=0;i<claxxs.length-1;i++){
					System.out.print(claxxs[i]+",");
				}
				System.out.print(claxxs[claxxs.length-1]);
			}
			System.out.println(")");
		}
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class中取出Method方法
 * 从当前代类中的获取所有的方法
 */
@Test
public void testMethod6_2(){
	try {
		Class clazz=Class.forName("User");
		
		Method[] methods=clazz.getDeclaredMethods();
		for(Method method: methods){
			System.out.print(method.getModifiers()+"  ");//获取访问修饰符
			System.out.print(method.getReturnType()+"  ");//获取返回类型
			System.out.print(method.getName()+"(");//获取方法名称
			//获取参数列表
			Class[] claxxs=method.getParameterTypes();
			if(claxxs!=null && claxxs.length>0){
				for(int i=0;i<claxxs.length-1;i++){
					System.out.print(claxxs[i]+",");
				}
				System.out.print(claxxs[claxxs.length-1]);
			}
			System.out.println(")");
		}
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class中取出Method方法
 * 从当前代类及其长辈类中的指定的公有方法
 */
@Test
public void testMethod6_3(){
	try {
		Class clazz=Class.forName("User");
		
		Method method=clazz.getMethod("setUserName", String.class);
		
		System.out.print(method.getModifiers()+"  ");//获取访问修饰符
		System.out.print(method.getReturnType()+"  ");//获取返回类型
		System.out.print(method.getName()+"(");//获取方法名称
		//获取参数列表
		Class[] claxxs=method.getParameterTypes();
		if(claxxs!=null && claxxs.length>0){
			for(int i=0;i<claxxs.length-1;i++){
				System.out.print(claxxs[i]+",");
			}
			System.out.print(claxxs[claxxs.length-1]);
		}
		System.out.println(")");
		
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (NoSuchMethodException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 从Class中取出Method方法
 * 从当前代类中获取的指定的方法
 */
@Test
public void testMethod6_4(){
	try {
		Class clazz=Class.forName("User");
		
		Method method=clazz.getDeclaredMethod("xxx", int.class,float.class);
		
		System.out.print(method.getModifiers()+"  ");//获取访问修饰符
		System.out.print(method.getReturnType()+"  ");//获取返回类型
		System.out.print(method.getName()+"(");//获取方法名称
		//获取参数列表
		Class[] claxxs=method.getParameterTypes();
		if(claxxs!=null && claxxs.length>0){
			for(int i=0;i<claxxs.length-1;i++){
				System.out.print(claxxs[i]+",");
			}
			System.out.print(claxxs[claxxs.length-1]);
		}
		System.out.println(")");
		
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (NoSuchMethodException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 通过Method对象可以获取方法的信息 访问修饰符 返回数据类型  方法名称(参数列表的类型)
 * 通过Method对象还可以调用方法,用反射的方式,可以调用任意方法
 * Object returnValue=Method对象.invoke(调用方法的对象名,方法的参数);//可以调用任意方法,通用方法调用
 * 需求:
 *   给一个对象中的私有数据赋值
 * 实现方案一:传统的静态的方式
 *   对象名.setXXX(参数);//在编译期间就确定好的调用关系
 * 实现方案二:用反射的方式调用setXXX(参数)方法,在运行期间才能确定调用此setXXX方法
 *   
 */
@Test
public void testMethod6_5(){
	//传统的方式
	User  user=new  User();
	user.setUserName("zhangsna ");//编译期间确定的调用关系
	//反射的方式
	try {
		Class clazz=Class.forName("User");
		Object obj=clazz.newInstance();
		Method method=clazz.getMethod("setUserName", String.class);
		Object returnValue=method.invoke(obj, "张三");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
//用反射的方式在运行期间确定调用方法
@Test
public void testMethod6_6(){
	try {
		//获取Class对象
		Class clazz=Class.forName("User");
		//反射的方式创建对象
		Object obj=clazz.newInstance();
		//通用set方法
		setMethod("userName",obj,"zhangsan");
		setMethod("userPassword",obj,"zs");
		setMethod("age",obj,20);
		//通用get方法
		Object username=getMethod("userName",obj);
		Object userpassword=getMethod("userPassword",obj);
		Object userage=getMethod("age",obj);
		System.out.println(username+"   "+userpassword+"   "+userage);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
/**
 * 通用存储数据的方法,主要目的是为了要演示反射调用方法 invoke
 * 我只是想让你们用反射能做出通用的功能,能做出通用的功能,提高开发效率
 * @param propertyName  属性名称
 * @param obj   调用方法的对象名 
 * @param args  方法的参数
 * @throws Exception
 * 分析步骤:
 * 1.获取Class对象
 * 2.根据属性的名称构建一个方法名
 *   属性名称第一个字母大写,前面加上set
 * 3.通过class对象反射获取所有的方法
 * 4.遍历所有的方法,匹配第二步的方法名
 * 5.如果匹配了就调用set方法
 *   如果没有匹配就什么都不做
 * 结论:
 *   就是在运行期间,根据原则寻找方法,如果找到方法就调用
 *   而不是在变期间就调用 
 */
private void setMethod(String propertyName,Object obj,Object...args)throws Exception{
	//获取Class对象
	Class clazz=obj.getClass();
	//set+U+serName-->setUserName
	String setterName="set"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1);
	/*//根据Class对象反射出类中的所有的方法
	Method[] methods=clazz.getDeclaredMethods();
	//循环遍历
	for(Method method:methods){
		//寻找类中是否有对应的set方法
		if(setterName.equals(method.getName())){
			//保证方法能够被访问调用
			method.setAccessible(true);
			Object returnValue=method.invoke(obj, args);
		}
	}*/
	Field field=clazz.getDeclaredField(propertyName);

	Method method=clazz.getDeclaredMethod(setterName, field.getType());
	method.setAccessible(true);
	Object returnValue=method.invoke(obj, args);
}
/**
 * 通用取值的方式
 * 
 * @param propertyName  属性名称
 * @param obj  调用方法的对象名
 * @return  方法的返回值
 * 分析步骤:
 * 1.获取Class对象
 * 2.根据属性名称 拼装一个get方法的名称
 *   把属性名第一字母大写,前面加上get
 * 3.根据Class对象反射出类中的所有的方法
 * 4.遍历所有的方法,匹配第二步的方法名称
 * 5.如果匹配上就调用getter方法,并把值返回
 * 
 */
private Object getMethod(String propertyName,Object obj){
	Object returnValue=null;
	try {
		//获取Class对象
		Class clazz=obj.getClass();
		//拼装方法名称
		String getterMethod="get"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1);
		/*//根据Class对象反射出所有的方法
		Method[] methods=clazz.getDeclaredMethods();
		//循环遍历所有的方法,匹配方法名称
		for(Method method: methods){
			if(getterMethod.equals(method.getName())){
				method.setAccessible(true);
				returnValue=method.invoke(obj);
			}
		}*/
		Method method=clazz.getDeclaredMethod(getterMethod);
		method.setAccessible(true);
		returnValue=method.invoke(obj);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return returnValue;
}
/**
 * 遍历所有构造,用反射的方式
 */
@Test
public void testMethod7_1(){
	try {
		Class clazz=Class.forName("User");
	
		Constructor[] cons=clazz.getConstructors();
		for(Constructor con: cons){
			System.out.print(con.getModifiers()+"  ");//访问修饰符
			System.out.print(con.getName()+"(");//构造函数的名字
			//获取构造的参数的类型
			Class[] claxxs=con.getParameterTypes();
			if(claxxs!=null && claxxs.length>0){
				for(int i=0;i<claxxs.length-1;i++){
					System.out.print(claxxs[i]+",");
				}
				System.out.println(claxxs[claxxs.length-1]);
			}			
			System.out.println(")");
		}
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

User类

public class User {
	private String userName;
	private String userPassword;
	String userAddress;
	protected int age;
	public String desc;
	public User(){}
	public User(String userName, String userPassword, String userAddress, int age, String desc) {
		this.userName = userName;
		this.userPassword = userPassword;
		this.userAddress = userAddress;
		this.age = age;
		this.desc = desc;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getUserAddress() {
		return userAddress;
	}

	public void setUserAddress(String userAddress) {
		this.userAddress = userAddress;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}
	private float xxx(int a,float b){
		return 0f;
	}
	protected void  yyy(String a,double b){
		
	}
	String zzz(String a,Date date){
		return null;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值