反射机制:(Class类)reflect
Class cl = Date.class//字节码:
1.如何得到各个字节码对应的实例对象(Class类型)
1.类名。class,for example, System.class-------->得到SYSTEM类对应的字节码
2.对象.getClass(), for example, new Date().getClass-------->得到Date这个对象的字节码。
3.Class.forName("类名"), for example, Class.forName("java.Util.Date");类加载器,将指定的类加载进来。数据库连接时要用到的。
2.基本概念:
反射就是把JAVA类中的各种成分映射成相应的JAVA类。例如,一个JAVA类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,
方法,构造方法,包等等信息也用一个个的JAVA类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。
表示JAVA类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用
相应类的实例对象来表示,他们是Filed,Method,Contructor,Package等等。
一个类中的每个成员都可以用相应的反射Api类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例
对象后有什么用呢??怎么用呢?这正是学习和应用反射的要点
Construct类(构造方法类)
得到指定的构造方法:Construtor constructor1 = Class.forName("java.lang.String").getConstrutor();
得到所有的构造方法:Construtor[] constructors Class.forName("java.lang.String").getConstrutors();
for example: 我们要写一个new String(new StringBuffer("abc"));
首先:我们必须利用反射拿到String对应的构造方法类中指定的构造方法;
即:Constrctor c1 = Class.forName("java.lang.String").getContructor(Buffere.class)
其次:利用返回的构造方法类创建的相应的构造方法的实例:
即:String str = (String)c1.newInstance(new StringBuffere("abc"));
注意:两次出现的StringBuffere的意义是不同的。前者是在确定得到的是哪个构造方法,后者是作为参数传递的,参与实例的初始化过程。
Field类(成员变量类)
Point p1 = new Point(3,5);
Field fieldY = p1.getClass(p1).getField("y");
注意:此时得到的值并不是某个对象的值(比如5),而是得到的是类的一个成员变量。要想得到具体的值,必须映射到某个具体的对象上去;
for example: fieldY.get(p1)==5; 此时得到的就是具体的值了。因为它映射到了具体的p1对象上去了。
如果该成员变量(X)是私有的(private),那么就必须要用特定的方法去拿私有的了变量了,
for example: Field fieldX = p1.getClass(p1).getDeclaredField("x"); 就算拿到了也不能直接访问的到。还要进行设置;
fieldX.setAccessible(true);此时该私有的成员变量就可以被访问了;
fieldX == 3;
Method类(成员方法类)
Method类代表某个类中的一个成员方法
得到类中的某个方法:
例子:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.Class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射的方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法。
对接受数组参数的成员方法进行反射:
for example: main()调用的例子: Person.main(new String[]{"111","2222"});
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null,(object)new String[]{"111","222"});//在传递参数的时候一定不要忘了(object)不然会编译出错,因为这样会让编译器拆开数组进行3个对象的传递
javaBean(内省)
String propertyName = "x"; //x--->X--->getX--->MethodGetX--->
使用反射和内省后:
1.PropertyDescriptor pd = new PropertyDescriptor(propertyName,Person.getClass)//得到变量的属性值。
2.Method methodGetX = pd.getReadMethod();//通过反射和内省得到相应方法
3.Obeject retVal = methodGetX.invoke(p);//调用方法,完成所有的步骤。