Java编程之反射-demo

       本节写了个Demo测试反射机制的主要方法,有些细节的东西没有再具体细化,把反射的主要功能都实现了一遍,代码如下:

public class TestReflect
{
	public static void main(String[] args) 		
	{
		//测试所有构造函数
		getAllConstructors();
		
		//测试私有构造函数
		getPrivateConstructor();
		
		//测试运行私有方法
		getPrivateMethod();
		
		//测试获取和设置属性
		getFields();
	}

	private static void getFields()
	{
		try
		{
			//加载类对象
			Class<?> c = Class.forName("reflect.domain.Human");
			//实例化Human对象
			Human human = (Human) c.newInstance();
			//获得Human对象所有属性
			Field[] fields = c.getDeclaredFields();
			for(int i = 0, size = fields.length; i < size; i++)
			{
				Field field = fields[i];
				System.out.println(field.toGenericString());
				String name = field.getName();
				//转换将属性名首字母大写
				if(!Character.isUpperCase(name.charAt(0)))
				{		       
		                    name = (new StringBuilder()).append(Character.toUpperCase(name.charAt(0))).append(name.substring(1)).toString();
				}
				//拼接获得属性设置方法名
				String setMethod = "set" + name;
				//获得属性设置Method
				Method method = c.getDeclaredMethod(setMethod, new Class[]{String.class});
				method.setAccessible(true);
				//执行属性设置方法
				method.invoke(human, new Object[]{"ss"});
			}
			human.introdude();
		}
		catch(Exception e)
		{
			//todo
		}		
	}

	private static void getPrivateMethod()
	{
		try
		{
			Class<?> c = Class.forName("reflect.domain.Human");
			Human human = (Human) c.newInstance();
			//获得指定方法名和参数类型的方法
			Method method = c.getDeclaredMethod("privateMethod", new Class[]{});
			//设置可访问
			method.setAccessible(true);
			//触发执行该方法
			method.invoke(human, new Object[]{});
		}
		catch(Exception e)
		{
			//todo
		}		
	}

	private static void getPrivateConstructor()
	{
		try
		{
			Class<?> c = Class.forName("reflect.domain.Human");
			//获得指定参数类型的构造函数
			Constructor cons = c.getDeclaredConstructor(new Class[]{String.class});
			//设置可访问
			cons.setAccessible(true);
			//初始化实例,根据传入的参数初始化
			Human human = (Human) cons.newInstance(new Object[]{"William"});
			//执行对象方法
			human.publicMethod();
			human.introdude();
		}
		catch(Exception e)
		{
			//todo
		}
		
	}

	private static void getAllConstructors()
	{
		try
		{
			Class<?> c = Class.forName("reflect.domain.Human");	
			//获得所有构造函数
			Constructor[] constructors = c.getDeclaredConstructors();
			Human human = null;
			for(int i = 0, size = constructors.length; i < size; i++)
			{
				Constructor cons = constructors[i];
				cons.setAccessible(true);
				//获得构造函数完整签名
				String consName = cons.toGenericString();
				//获得该构造函数的参数
				String[] arg1 = consName.split("\\(");
				String[] arg2 = arg1[1].split("\\)");				
				if(0 == arg2.length)
				{
					//如果参数为0,调用无参构造函数实例化
					human = (Human) cons.newInstance();
					human.introdude();
				}
				else
				{	
					//否则根据参数个数和类型分别实例化,如果不知道参数类型,也可以用反射机制获得,这里不再麻烦
					String[] args = arg2[0].split(",");
					if(1 == args.length)
					{
						human = (Human) cons.newInstance(new Object[]{"Ann"});
						human.introdude();
					}
					else if(2 == args.length)
					{
						human = (Human) cons.newInstance(new Object[]{"Ann", "female"});
						human.introdude();
					}	
				}			
			}
		}
		catch(Exception e)
		{
			//todo
		}		
	}
}

         反射机制允许一个类使用另一个类,即使当前者被编译的时候后者还根本不存在。然后,这种能力也要付出代价:

      1.丧失了编译时类型检查的好处,包括异常检查。如果程序试图用反射方式调用不存在或不可访问的方法,在运行时它可能会失败,因此需要做好防护措施;

      2.执行反射访问所需要的代码非常笨拙和冗长。编写乏味,阅读困难;

      3.性能损失。反射方法调用比普通方法调用慢很多。

      以上来自<<Effective Java>>。

      因此,在普通的方法调用中不需要使用反射,在一些复杂程序中,而且需要使用在编译时无法知道的对象时,才考虑使用反射机制。

      反射是一些框架技术的核心,比如Spring,Struts2等,对于反射的原理还需要进一步掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值