-------android培训、java培训、期待与您交流! ----------
反射的基石Class类
字节码:硬盘上类的代码编译成二进制代码。
获得类的字节码的方法:
Perso p = new Person();
1.
2.Class cls2 = p1.getClass();
3.Class cls3 = Class.forName("java.lang.String");//Class类中的静态方法 jvm中还没有这个类的字节码,就用类加载器去把类的字节码加载进内存来,然后缓存起来返回该字节码。
String str1 = "abc";
System.out.println(cls1.isPrimitive());//false 判断该类型是否是原始类型。
System.out.println(int.class == Integer.TYPE);//.TYPE包装类型所包装的基本类型的字节码。
System.out.println(int[].class.isPrimitive());//数组也是一种类型,数组不是原始类型。
System.out.println(int[].class.isArray());//isArray()判断该类型是否是数组。
九个预定义Class实例对象:八个基本类型 和void
****反射:就是把Java类中的各种成分映射成相应的Java类。
1.构造方法的反射应用Constructor类。
Constructor [] constructors = Class.forName("java.lang.String").getConstructors();//得到所有构造方法返回一个数组
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);//得到StringBuffer参数类型的构造方法。因为1.5新特性可变参数,可以写若干个参数,
2.成员类的反射应用Field类。
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");//filedY的值是多少?是5.错!filldy不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
fieldY.get(pt1);//取出y这个变量在pt1这个对象中Y这个成员的值。
Filed fieldX = pt1.getClass().getDeclaredField("x");//只要是声明的变量都可以获得不管修饰符。
fieldX.setAccessible(true);//取消访问权限。
fieldX.get(pt1); //这种取出私有成员变量的值的方法叫做暴力反射。
把一个对象中所有String类型变量的b换成a
private static void changeStringValue(Object obj) throws Exception{
3.成员方法的反射应用Method类。
得到方法:
Method methodCharAt = String.class.getMethod("charAt",int.class);
methodCharAt.invoke(str1,1);//在str1对象上调用charAt方法,方法参数为1//如果第一个参数为null,则为静态方法。
用反射方式执行某个类中的main方法。
为什么要用反射的方式去调?
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName ).getMethod("main",String[].class);
mainMethod.invoke(null,new String[]{"111","222","333"});//不对 因为1.5可变参数把String[]当做一个Object数组给打开,吧每一个元素分别作为一个参数。
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});把String数组再打包当做Object数组中的第一个元素。
mainMethod.invoke(null,(Object)new String[]{"111","222","333"});//这样也可以
4.数组的反射
int [] a2 = new int[4];
int[][]a3 = new int[2][3];
String[]a4 = new String[3];
Object aObj1 = a1;
Object aObj2 = a4;
Object[] aObj3 = a1;//错。a1是一个Object。不能把他当做Object数组
Object[] aObj4 = a3;//一维数组是一个Object。二维数组可以看做Object数组中的元素是一维数组
Object[] aObj5 = a4;//String是一个Object,String数组可以看做Object中的元素是String
Arrays.asList(a1);//把al当做一个Object作为参数
Arrays.asList(a4);//把String数组当做一个Object数组,数组的元素作为参数,存入集合
数组的反射应用
private static void printObject(Object obj) {
反射的作用-->实现框架功能
InputStream ips = new FileInputStream("config.properties");
Properties props = new Properties();
props.load(ips);
ips.close();
String className = props.getProperty("className");
用类加载器的方式管理资源和配置文件。
Myeclipse把所有的.java文件编译成.class文件存到ClassPath指定目录下。把其他文件原封不动存到ClassPath指定目录下。
Strus框架的配置文件都是放在ClassPath指定的目录下,原因就是用类加载器加载的配置文件。
ReflectTest2.class.getResourceAsStream("resource/config.properties");//相对于ReflectTest2这个类所在包下的Resource目录下的config.properties。只需要写上配置文件的名字,不需要写上目录名,没用/打头表示相对路径,表示配置文件在我这个类所在的包
------- android培训、java培训、期待与您交流! ----------详细请查看:http://edu.csdn.net