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

java核心技术之反照

2012-12-28 
java核心技术之反射能够分析类能力的程序成为反射。使用反射的主要对象是工具构造者,而非应用程序员。1、Clas

java核心技术之反射


能够分析类能力的程序成为反射。
使用反射的主要对象是工具构造者,而非应用程序员。
1、Class
返回Class类得实例有几种方式:

        //a        Girl g1 = new Girl();        Class c0 = g1.getClass();        //b        String className = "com.gong.reflect.Girl";        Class c1 = Class.forName(className);        //c        Class c2 = Girl.class;
?


2、检查类结构
检查类结构--java反射机制的重要内容
java.lang.reflect包中三个类Field、Method、Constructor分别用于描述类得域、方法和构造器。

public class ReflectionTest {    public static void main(String[] args) {        // read class name from command line args or user input        String name;        if (args.length > 0)            name = args[0];        else {            Scanner in = new Scanner(System.in);            System.out.println("Enter class name (e.g. java.util.Date): ");            name = in.next();        }        try {            Class cl = Class.forName(name);            Class supercl = cl.getSuperclass();            String modifiers = Modifier.toString(cl.getModifiers());            //getModifiers()返回一个描述构造器、方法或域的修饰符的整型数值            System.out.println(cl.getModifiers());            //Modifier.toString返回对应modifier位设置的修饰符的字符串表示            System.out.println("modifiers:"+modifiers);            if (modifiers.length() > 0)                System.out.print(modifiers + " ");                System.out.print("class " + name);            if (supercl != null && supercl != Object.class)                System.out.print(" extends " + supercl.getName());            System.out.print("\n{\n");            printConstructors(cl);            System.out.println();            printMethods(cl);            System.out.println();            printFields(cl);            System.out.println("}");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        System.exit(0);    }    public static void printConstructors(Class cl) {        Constructor[] constructors = cl.getDeclaredConstructors();        for (Constructor c : constructors) {            String name = c.getName();            System.out.print("   ");            String modifiers = Modifier.toString(c.getModifiers());            if (modifiers.length() > 0)                System.out.print(modifiers + " ");            System.out.print(name + "(");            // print parameter types            Class[] paramTypes = c.getParameterTypes();            for (int j = 0; j < paramTypes.length; j++) {                if (j > 0)                    System.out.print(", ");                System.out.print(paramTypes[j].getName());            }            System.out.println(");");        }    }    public static void printMethods(Class cl) {        Method[] methods = cl.getDeclaredMethods();        for (Method m : methods) {            Class retType = m.getReturnType();            String name = m.getName();            System.out.print("   ");            // print modifiers, return type and method name            String modifiers = Modifier.toString(m.getModifiers());            if (modifiers.length() > 0)                System.out.print(modifiers + " ");            System.out.print(retType.getName() + " " + name + "(");            // print parameter types            Class[] paramTypes = m.getParameterTypes();            for (int j = 0; j < paramTypes.length; j++) {                if (j > 0)                    System.out.print(", ");                System.out.print(paramTypes[j].getName());            }            System.out.println(");");        }    }    public static void printFields(Class cl) {        Field[] fields = cl.getDeclaredFields();        for (Field f : fields) {            Class type = f.getType();            String name = f.getName();            System.out.print("   ");            String modifiers = Modifier.toString(f.getModifiers());            if (modifiers.length() > 0)                System.out.print(modifiers + " ");            System.out.println(type.getName() + " " + name + ";");        }    }}
?


3、运行时反射分析对象
反射机制的默认行为受限于java访问控制。

public class FieldTest {    public static void main(String[] args) {        try {            Girl g = new Girl("lady gaga", 26, 38);            Class cl = g.getClass();            Field f = cl.getDeclaredField("name");            //为反射对象设置可访问标志            //true表示屏蔽java语言检查,对象的私有属性也可以被查询和设置            f.setAccessible(true);            Object o = f.get(g);            System.out.println(o);        }catch(SecurityException e) {            e.printStackTrace();        }catch(NoSuchFieldException e) {            e.printStackTrace();        }catch(IllegalArgumentException e) {            e.printStackTrace();        }catch(IllegalAccessException e) {            e.printStackTrace();        }    }}
?


4、利用反射编写通用数组代码
java.lang.reflect包中的Array类允许动态地创建数组。

public class ArrayGrowTest {    public static void main(String[] args) {        int[] a = { 1, 2, 3 };        a = (int[]) goodArrayGrow(a);        arrayPrint(a);        String[] b = { "Tom", "Dick", "Harry" };        b = (String[]) goodArrayGrow(b);        arrayPrint(b);        System.out.println("The following call will generate an exception.");        b = (String[]) badArrayGrow(b);    }       static Object[] badArrayGrow(Object[] a) {        int newLength = a.length * 11 / 10 + 10;        //新创建的对象数组不能转成String数组        Object[] newArray = new Object[newLength];        System.arraycopy(a, 0, newArray, 0, a.length);        return newArray;    }    static Object goodArrayGrow(Object a) {        Class cl = a.getClass();        if (!cl.isArray()) return null;        Class componentType = cl.getComponentType();        int length = Array.getLength(a);        int newLength = length * 11 / 10 + 10;        //componentType数组元素类型,newLength数组的长度        Object newArray = Array.newInstance(componentType, newLength);        System.arraycopy(a, 0, newArray, 0, length);        return newArray;    }    static void arrayPrint(Object a) {        Class cl = a.getClass();        if (!cl.isArray()) return;        Class componentType = cl.getComponentType();        int length = Array.getLength(a);        System.out.print(componentType.getName() + "[" + length + "] = { ");        for (int i = 0; i < Array.getLength(a); i++)            System.out.print(Array.get(a, i) + " ");        System.out.println("}");    }}
?


5、方法指针
执行对象方法或静态方法

public class MethodPointerTest {    public static void main(String[] args) throws Exception {        Method square = MethodPointerTest.class.getMethod("square", double.class);        Method sqrt = Math.class.getMethod("sqrt", double.class);        printTable(1, 10, 10, square);        printTable(1, 10, 10, sqrt);    }    public static double square(double x) {        return x * x;    }    public static void printTable(double from, double to, int n, Method f) {        System.out.println(f);        double dx = (to - from) / (n - 1);        for (double x = from; x <= to; x += dx) {            try {                double y = (Double) f.invoke(null, x);                System.out.printf("%10.4f | %10.4f%n", x, y);            } catch (Exception e) {                e.printStackTrace();            }        }    }}


建议在必要的时候才使用Method对象,最好使用接口和内部类。
不要过多使用反射
反射很脆弱,编译器很难帮助发现程序中的错误。任何错误只能在运行时发现,并导致异常。

热点排行