首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java 反照与自省

2013-12-26 
java 反射与自省Class object 诞生管道示例运用getClass()注:每个class 都有此函数String str abcCla

java 反射与自省
Class object 诞生管道示例运用getClass()注:每个class 都有此函数String str = "abc";Class c1 = str.getClass();运用Class.getSuperclass()2Button b = new Button();Class c1 = b.getClass();Class c2 = c1.getSuperclass();运用static methodClass.forName()(最常被使用)Class c1 = Class.forName ("java.lang.String");Class c2 = Class.forName ("java.awt.Button");Class c3 = Class.forName ("java.util.LinkedList$Entry");Class c4 = Class.forName ("I");Class c5 = Class.forName ("[I");运用.class 语法Class c1 = String.class;Class c2 = java.awt.Button.class;Class c3 = Main.InnerClass.class;Class c4 = int.class;Class c5 = int[].class;运用primitive wrapper classes的TYPE 语法?Class c1 = Boolean.TYPE;Class c2 = Byte.TYPE;Class c3 = Character.TYPE;Class c4 = Short.TYPE;Class c5 = Integer.TYPE;Class c6 = Long.TYPE;Class c7 = Float.TYPE;Class c8 = Double.TYPE;Class c9 = Void.TYPE;1Java 允许多种管道生成Class object?2.2??? Java classes 组成分析以图2的java.util.LinkedList为例,将Java class的定义大卸八块,每一块分别对应图3所示的Reflection API。?package java.util; ??????????????? //(1)import java.lang.*; ?????????????? //(2)public class LinkedList<E> ???????????? //(3)(4)(5)extends AbstractSequentialList<E> ??????????????//(6)implements List<E>, Queue<E>,Cloneable, java.io.Serializable ?????? ??????//(7){private static class Entry<E> { … }//(8)public LinkedList() { … } ????????? ???????//(9)public LinkedList(Collection<? extends E> c) { … }public E getFirst() { … } ????????? ???????//(10)public E getLast() { … }private transient Entry<E> header = …;??????? //(11)private transient int size = 0;}2:将一个Java class 大卸八块,每块相应于一个或一组Reflection APIs(图3)。?2.3??? Java classes 各成份所对应的Reflection APIs图2的各个Java class成份,分别对应于图3的Reflection API,其中出现的Package、Method、Constructor、Field等等classes,都定义于java.lang.reflect。本表并非Reflection APIs 的全部。

?

Java class 内部模块(参见图3)Java class 内部模块说明相应之Reflection API,多半为Class methods。返回值类型(return type)(1) packageclass隶属哪个packagegetPackage()Package(2) importclass导入哪些classes无直接对应之API。解决办法见图5-2。?(3) modifierclass(或methods, fields)的属性?int getModifiers()Modifier.toString(int)Modifier.isInterface(int)intStringbool(4) class name or interface nameclass/interface名称getName()String(5) type parameters参数化类型的名称getTypeParameters() TypeVariable <Class>[](6) base classbase class(只可能一个)getSuperClass()Class(7) implemented interfaces实现有哪些interfacesgetInterfaces()Class[]?(8) inner classes内部classesgetDeclaredClasses()Class[](8') outer class如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。getDeclaringClass()Class(9) constructors构造函数getDeclaredConstructors()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Constructor[](10) methods操作函数getDeclaredMethods()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Method[](11) fields字段(成员变量)getDeclaredFields()不论 public 或private 或其它access level,皆可获得。另有功能近似之取得函数。Field[]3Java class大卸八块后(如图2),每一块所对应的Reflection API3?????? Java例程Model.java?package RefInt;?import java.io.Serializable;import java.util.Date;?publicclass Model implements Serializable {???? privatestaticfinallongserialVersionUID = -162798607158235676L;???? publicstatic String id = "111111";??? public String name = "haha";??? privateintage ;??? private Date b;??? ??? publicint getAge() {?????? returnage;??? }??? publicvoid setAge(int age) {?????? this.age = age;??? }??? public Date getB() {?????? returnb;??? }??? publicvoid setB(Date b) {?????? this.b = b;??? }??? public String getName() {?????? returnname;??? }??? publicvoid setName(String name) {?????? this.name = name;??? }}3.1??? 反射RefInt.java?package RefInt;?import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Arrays;?publicclass RefInt {??? ??? publicstaticvoid main(String[] args) {?????? System.out.println("f_1()");?????? f_1();?????? System.out.println("f_2()");?????? f_2();?????? System.out.println("f_3()");?????? f_3();?????? System.out.println("f_4()");?????? f_4();?????? System.out.println("getArrayByIndex()");?????? int[] a = {10,2,3,5};?????? String[] s = {"aabc","aaabc","def","f"};?????? // 数组排序?????? Arrays.sort(s);?????? System.out.println(getArrayByIndex(s,0));?????? System.out.println(getArrayByIndex(a,0));?????? System.out.println(getArrayByIndex(a,3));?????? Arrays.sort(a);?????? System.out.println(getArrayByIndex(a,0));?????? System.out.println(getArrayByIndex(a,3));?????? Array.set(a, 0, -1);?????? System.out.println(getArrayByIndex(a,0));??? }???? /**??? ?*获得数组o下标为index的值??? ?*@paramo??? ?*@paramindex??? ?*@return??? ?*/??? publicstatic Object getArrayByIndex(Object o , int index) {?????? return Array.get(o, index);??? }??? ??? /**??? ?*通过类名得到类描述对象??? ?*通过类描述对象获得类模式(此类为public)??? ?*/??? publicstaticvoid f_4() {?????? try {?????????? Class class_my = Class.forName("RefInt.Model");?????????? int m = class_my.getModifiers();?????????? System.out.println(class_my.getModifiers());?????????? if (Modifier.isPublic(m))?????? ???????? System.out.println("public");??????? } catch (ClassNotFoundException e) {?????????? e.printStackTrace();?????? } catch (SecurityException e) {?????????? e.printStackTrace();?????? } catch (IllegalArgumentException e) {?????????? e.printStackTrace();?????? }??? }??? ??? /**??? ?*通过类名得到类描述对象??? ?*通过类描述对象获得属性对象列表并显示其属性??? ?*/??? publicstaticvoid f_3() {?????? try {?????????? Class class_my = Class.forName("RefInt.Model");?????????? // 只能得到属性是public的Field?????????? Field[] publicFields = class_my.getFields();?????????? for (int i = 0; i < publicFields.length; i++) {????????????? String fieldName = publicFields[i].getName();????????????? Class typeClass = publicFields[i].getType();????????????? String fieldType = typeClass.getName();????????????? System.out.println("Name: " + fieldName + ", Type: " + fieldType);?????????? }?????? } catch (ClassNotFoundException e) {?????????? e.printStackTrace();?????? }??? }??? /**??? ?*通过实体对象获得类描述对象??? ?*通过累描述对象获得指定属性对象??? ?*通过属性对象实例得到属性名和属性值??? ?*/??? publicstaticvoid f_2() {?????? Model model = new Model();?????? //属性必须是public,否则抛出NoSuchFieldException异常?????? String sfiled = "name";?????? Class class_my = model.getClass();?????? try {?????????? Field filed = class_my.getField(sfiled);?????????? System.out.println(filed.getName());?????????? System.out.println(filed.get(model));?????? } catch (SecurityException e) {?????????? e.printStackTrace();?????? } catch (NoSuchFieldException e) {?????????? e.printStackTrace();?????? } catch (IllegalArgumentException e) {?????????? e.printStackTrace();?????? } catch (IllegalAccessException e) {?????????? e.printStackTrace();?????? }??? }??? ??? /**??? ?*通过类名获得实体对象??? ?*通过属性名称获取实体对象属性值??? ?*/??? publicstaticvoid f_1() {?????? try {?????????? Class cla = Class.forName("RefInt.Model");?????????? Object o = cla.newInstance();?????????? String methodName = "getName";?????????? Method m = cla.getMethod(methodName, (Class[])null);?????????? System.out.println(m.invoke(o, (Object[])null));?????????? methodName = "getAge";?????????? m = cla.getMethod(methodName, (Class[])null);?????????? System.out.println(m.invoke(o, (Object[])null));?????????? methodName = "getB";?????????? m = cla.getMethod(methodName, (Class[])null);?????????? System.out.println(m.invoke(o, (Object[])null));?????? } catch (ClassNotFoundException e) {?????????? e.printStackTrace();?????? } catch (InstantiationException e) {?????????? e.printStackTrace();?????? } catch (IllegalAccessException e) {?????????? e.printStackTrace();?????? } catch (SecurityException e) {?????????? e.printStackTrace();?????? } catch (NoSuchMethodException e) {?????????? e.printStackTrace();?????? } catch (IllegalArgumentException e) {?????????? e.printStackTrace();?????? } catch (InvocationTargetException e) {?????????? e.printStackTrace();?????? }??? }}?3.2??? 内省一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。Intro.java?package RefInt;?import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;?publicclass Intro {??? publicstaticvoid main(String[] args) {?????? Model m = new Model();?????? try {?????????? // 从其所在位置开始停止分析的基类。stopClass 或其基类中的所有方法/属性/事件都将在分析中被忽略。?????????? BeanInfo beanInfor = Introspector.getBeanInfo(m.getClass(),Object.class);?????????? PropertyDescriptor[] p = beanInfor.getPropertyDescriptors();?????????? for(int i=0;i<p.length;i++){????????????? System.out.println(p[i].getName()+"="+????????????? ??????? p[i].getReadMethod().invoke(m,(Object[])null));??? ??????? }??????? } catch (IntrospectionException e) {?????????? e.printStackTrace();?????? } catch (IllegalArgumentException e) {?????????? e.printStackTrace();?????? } catch (IllegalAccessException e) {?????????? e.printStackTrace();?????? } catch (InvocationTargetException e) {?????????? e.printStackTrace();?????? }??? }}

热点排行