JAVA-反射机制(2)

来源:互联网 发布:程序化交易软件下载 编辑:程序博客网 时间:2024/05/29 14:21

由于篇幅原因,Person类统计为

class Person{    public Person() {       }    public Person(String name){        this.name=name;    }    public Person(int age){        this.age=age;    }    public Person(String name, int age) {        this.age=age;        this.name=name;    }    public String getName() {        return name;    }    public int getAge() {        return age;    }    @Override    public String toString(){        return "["+this.name+"  "+this.age+"]";    }    private String name;    private int age;}

主类hello所在包名为:Reflect
6.取得其他类中的父类

class hello{    public static void main(String[] args) {        Class<?> demo=null;        try{            demo=Class.forName("Reflect.Person");        }catch (Exception e) {            e.printStackTrace();        }        //取得父类        Class<?> temp=demo.getSuperclass();        System.out.println("继承的父类为:   "+temp.getName());    }}

【运行结果】
继承的父类为: java.lang.Object

7.获得其他类中的全部构造函数
//这个例子需要在程序开头添加import java.lang.reflect.*;

class hello{    public static void main(String[] args) {        Class<?> demo=null;        try{            demo=Class.forName("Reflect.Person");        }catch (Exception e) {            e.printStackTrace();        }        Constructor<?>cons[]=demo.getConstructors();        for (int i = 0; i < cons.length; i++) {            System.out.println("构造方法:  "+cons[i]);        }    }}

【运行结果】:
构造方法: public Reflect.Person()
构造方法: public Reflect.Person(java.lang.String)

8.取得其他类的全部属性,将这些整理在一起,也就是通过class取得一个类的全部框架

class hello {    public static void main(String[] args) {        Class<?> demo = null;        try {            demo = Class.forName("Reflect.Person");        } catch (Exception e) {            e.printStackTrace();        }        System.out.println("===============本类属性========================");        // 取得本类的全部属性        Field[] field = demo.getDeclaredFields();        for (int i = 0; i < field.length; i++) {            // 权限修饰符            int mo = field[i].getModifiers();            String priv = Modifier.toString(mo);            // 属性类型            Class<?> type = field[i].getType();            System.out.println(priv + " " + type.getName() + " "                    + field[i].getName() + ";");        }        System.out.println("===============实现的接口或者父类的属性========================");        // 取得实现的接口或者父类的属性        Field[] filed1 = demo.getFields();        for (int j = 0; j < filed1.length; j++) {            // 权限修饰符            int mo = filed1[j].getModifiers();            String priv = Modifier.toString(mo);            // 属性类型            Class<?> type = filed1[j].getType();            System.out.println(priv + " " + type.getName() + " "                    + filed1[j].getName() + ";");        }    }}

【运行结果】:
===============本类属性========================
private java.lang.String sex;
===============实现的接口或者父类的属性========================
public static final java.lang.String name;
public static final int age;

9.通过反射调用其他类中的方法

class hello {    public static void main(String[] args) {        Class<?> demo = null;        try {            demo = Class.forName("Reflect.Person");        } catch (Exception e) {            e.printStackTrace();        }        try{            //调用Person类中的sayChina方法            Method method=demo.getMethod("sayChina");            method.invoke(demo.newInstance());            //调用Person的sayHello方法            method=demo.getMethod("sayHello", String.class,int.class);            method.invoke(demo.newInstance(),"Rollen",20);        }catch (Exception e) {            e.printStackTrace();        }    }}

【运行结果】:
hello ,china
Rollen 20

10.调用其他类的set和get方法

class hello {    public static void main(String[] args) {        Class<?> demo = null;        Object obj=null;        try {            demo = Class.forName("Reflect.Person");        } catch (Exception e) {            e.printStackTrace();        }        try{         obj=demo.newInstance();        }catch (Exception e) {            e.printStackTrace();        }        setter(obj,"Sex","男",String.class);        getter(obj,"Sex");    }    /**     * @param obj   操作的对象     * @param att   操作的属性     * */    public static void getter(Object obj, String att) {        try {            Method method = obj.getClass().getMethod("get" + att);            System.out.println(method.invoke(obj));        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * @param obj   操作的对象         * @param att   操作的属性     * @param value 设置的值     * @param type  参数的属性     * */    public static void setter(Object obj, String att, Object value,            Class<?> type) {        try {            Method method = obj.getClass().getMethod("set" + att, type);            method.invoke(obj, value);        } catch (Exception e) {            e.printStackTrace();        }    }}// end class

【运行结果】:

11.通过反射操作属性

class hello {    public static void main(String[] args) throws Exception {        Class<?> demo = null;        Object obj = null;      demo = Class.forName("Reflect.Person");       obj = demo.newInstance();        Field field = demo.getDeclaredField("sex");        field.setAccessible(true);        field.set(obj, "男");        System.out.println(field.get(obj));    }}// end class

12.通过反射取得并修改数组的信息

import java.lang.reflect.*;class hello{    public static void main(String[] args) {        int[] temp={1,2,3,4,5};        Class<?>demo=temp.getClass().getComponentType();        System.out.println("数组类型: "+demo.getName());        System.out.println("数组长度  "+Array.getLength(temp));        System.out.println("数组的第一个元素: "+Array.get(temp, 0));        Array.set(temp, 0, 100);        System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0));    }}

【运行结果】:
数组类型: int
数组长度 5
数组的第一个元素: 1
修改之后数组第一个元素为: 100

13.通过反射修改数组大小

class hello{    public static void main(String[] args) {        int[] temp={1,2,3,4,5,6,7,8,9};        int[] newTemp=(int[])arrayInc(temp,15);        print(newTemp);        System.out.println("=====================");        String[] atr={"a","b","c"};        String[] str1=(String[])arrayInc(atr,8);        print(str1);    }    /**     * 修改数组大小     * */    public static Object arrayInc(Object obj,int len){        Class<?>arr=obj.getClass().getComponentType();        Object newArr=Array.newInstance(arr, len);        int co=Array.getLength(obj);        System.arraycopy(obj, 0, newArr, 0, co);        return newArr;    }    /**     * 打印     * */    public static void print(Object obj){        Class<?>c=obj.getClass();        if(!c.isArray()){            return;        }        System.out.println("数组长度为: "+Array.getLength(obj));        for (int i = 0; i < Array.getLength(obj); i++) {            System.out.print(Array.get(obj, i)+" ");        }    }}

【运行结果】:
数组长度为: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
数组长度为: 8
a b c null null null null null

14.动态代理

class test{}class hello{    public static void main(String[] args) {        test t=new test();        System.out.println("类加载器  "+t.getClass().getClassLoader().getClass().getName());    }}

【程序输出】:
类加载器 sun.misc.Launcher$AppClassLoader

其实在java中有三种类类加载器。
1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。

package Reflect;import java.lang.reflect.*;//定义项目接口interface Subject {    public String say(String name, int age);}// 定义真实项目class RealSubject implements Subject {    @Override    public String say(String name, int age) {        return name + "  " + age;    }}class MyInvocationHandler implements InvocationHandler {    private Object obj = null;    public Object bind(Object obj) {        this.obj = obj;        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj                .getClass().getInterfaces(), this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        Object temp = method.invoke(this.obj, args);        return temp;    }}class hello {    public static void main(String[] args) {        MyInvocationHandler demo = new MyInvocationHandler();        Subject sub = (Subject) demo.bind(new RealSubject());        String info = sub.say("Rollen", 20);        System.out.println(info);    }}

【运行结果】:
Rollen 20

类的生命周期
在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。
类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前
链接就是把二进制数据组装为可以运行的状态。
链接分为校验,准备,解析这3个阶段:
校验一般用来确认此二进制文件是否适合当前的JVM(版本),
准备就是为静态成员分配内存空间,。并设置默认值
解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)。
完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。当没有任何引用指向Class对象时就会被卸载,结束类的生命周期。

原创粉丝点击