黑马程序员_10_高新技术之反射

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

反射的概念

反射就是把Java类中的各种成分映射成相应的java类。

例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。

反射的基石:Class类
java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class。
比如:中多的人用一个Person类表示,众多的java类就用Class类表示。
对比提问:Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,Class代表java类,它的各个实例对象又分别对应什么呢?
1,对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码,等等。
2,一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可以分别用一个个的对象来表示,这些对象具有相同的类型,这个类型是什么?
如何得到各个字节码对应的实例对象(Class类型)
1.类名.class,例如,System.class;
2.对象.getClass(),  例如,new Date().getClass();
3.Class.forName("类名"),例如,Class.forName("java.util.Date");
例:Class cls=String.class  得到String类的字节码

九个预定义的Class实例对象:八个基本类型加void。例:int.class==Integer.TYPE

一.构造方法的反射应用:Constructor类
Constructor类代表某个类中的一个构造方法
得到某个类中的所有构造方法:Consturctor consturctors[] = Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:Constructor constructor=
 Class.forName("java.lang.String").getConstructor(StringBuffer.class);
通过反射创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式:String str=constructor.newInstance(new StringBuffer("abc"));
注:调用获得的方法时要用到上面相同类型的实例对象。

二.成员变量的反射应用:Filed类
Filed类代表某个类中的一个成员变量。
得到某类中成员变量:
假设有个Person类含有成员变量name
Person p=new Person("lisi");//新建一个Person对象,name为lisi
Field fiedName=p.getClass.getFiled("name");//得到Person类中成员
String pName = filedName.get(p);//得到p对象中的name值。
p.getClass.getDeclaredFiled("成员名"); 得到私有权限的类中成员。
filedName.setAccessible(true); 暴力反射,不论权限,都可以操作该成员。

成员变量反射的综合案例:把ReflectPoint中3个字符串中的b改成a.
class ReflectPoint 
{
	public String s="ball";
	public String s="basketball";
	public String s1="itcast";
}



class ReflectTest2
{
	public static void main(String[] args) throws Exception
	{
		ReflectPoint rp = new ReflectPoint();
		Field[] fields=rp.getClass().getFields();//得到类中所有成员变量
		for (Field field:fields )//遍历成员变量
		{
			if(field.getType() == String.class)//如果field的类型为String
			{
				String oldStr=(String)field.get(rp);//获得字符串
				String newStr = oldStr.replace("b","a");//修改字符串
				field.set(rp,newStr);//设置成新的字符串
			}
		}
	}
}
三.成员方法的反射:Method类。
Method类代表某个类中的一个成员方法。
得到类中的一个方法,例:Method charAt=
Class.forName("java.lang.String").getMethod("charAt",int.class);//String类中的参数为int的charAt(int i)方法
调用方法:
1.通常方式:str.charAt(1);
2.反射方式:chatAt.invoke(str,1);

综合案例:对接受数组参数的成员方法进行反射。用反射的方式执行某个类中的main方法。
运行方法 : java ReflectTest TestArguments
class ReflectTest
{
	public static void main(String[] args) throws Exception
	{
		String startClassName = args[0];//得到类名
		Method mainMethod = Class.forName(startClassName).getMethod("main",String[].class);//得到main方法
		mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});//使用该类的main方法,静态方法写null。
	}
}
class TestArguments
{
	public static void main(String[] args)
	{
		for(String arg : args)
			System.out.println(arg);
		
	}
}
数组与Object的关系:
Object o1=new int[3];   对
Object[] o2=new int[3]; 错
Object[] o3=new int[3][4]  对
Object[] o4=new String[3] 对
Object[] o5=new String[3] 对
如果数组的维数相同,并且类型相同,那么它们的字节码是一样的。



------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值