java笔记(八):反射

来源:互联网 发布:淘宝上买气排有记录吗 编辑:程序博客网 时间:2024/06/03 18:52

java中的反射,是指在运行时,对于任意一个类,都可以知道这个类的所有属性和方法,对于任意一个对象,都能调用该对象的所有属性和方法。

反射机制主要提供了如下功能,
在运行时:

  • 判断一个对象所属的类
  • 构造一个类的对象
  • 判定一个类的成员变量和方法
  • 调用一个对象的方法
  • 生成动态代理

判断一个对象所属的类

根据对象获取该类,或者根据类名获得该类的Class对象。

A t = new B();Class c1 = t.getClass();Class c2 = B.class;Class c3 = null;try {    c3 = Class.forName("B");} catch (ClassNotFoundException e) {    e.printStackTrace();}System.out.println(c1 == c2);  //trueSystem.out.println(c1 == c3);  //trueSystem.out.println(c1);  //class Bclass A{}class B extends A{}

判断该对象的父类和接口方法如下:

A t = new B();Class c1 = t.getClass();System.out.println(c1.getSuperclass());System.out.println(c1.getInterfaces()[0]);

构造一个类的对象

首先需要获得该类的Class实例,然后通过newInstance()方法或者getConstructors()方法进行实例化。

//使用newInstance()赋值try {    Class classB = B.class;    B b = (B)classB.newInstance();    System.out.println(b.i);  //2} catch(InstantiationException e){    e.printStackTrace();} catch (IllegalAccessException e) {    e.printStackTrace();}class A{}class B extends A implements I{    public int i = 2;}
//使用getConstructors()赋值Class classB = B.class;Constructor<?> cons[] = classB.getConstructors();for (int i = 0; i < cons.length; i++) {    Class<?> clazzs[] = cons[i].getParameterTypes();    System.out.print("cons[" + i + "] (");    for (int j = 0; j < clazzs.length; j++) {        System.out.print(clazzs[j].getName()+"    ");    }    System.out.println(")");}//上述的输出结果如下://constructor [0]:(int    )//constructor [1]:(int    int     )try {    B b = (B) cons[2].newInstance(3, 5);    System.out.println(b.i);  //3} catch (InstantiationException e) {    e.printStackTrace();} catch (IllegalAccessException e) {    e.printStackTrace();} catch (InvocationTargetException e) {    e.printStackTrace();}class A{}class B extends A implements I{    public int i = 2;    public B(int i){        this.i = i;    }    public B(int i, int j){        this.i = i;    }}

两者的不同在于,前者是使用Class的newInstance()方法进行初始化,不带参数;后者使用Constructor的newInstance()方法进行初始化,可以带参数。
其中,第二个方法的代码使用了Constructor的getConstructors方法,该方法返回的是参数的类型。注意,参数的类型也是类,因此返回的参数类型是Class<T>

判定类的成员变量和方法

Class classA = A.class;//输出属性Field[] fields = classA.getFields();for (Field field:fields ){    Class type = field.getType();    String prive = Modifier.toString(field.getModifiers());    System.out.println(prive+" "+type.getName()+" "+field.getName());}//public java.lang.String i4//public double i5//输出方法Method method[] = classA.getDeclaredMethods();for (int i = 0; i < method.length; ++i) {    Class<?> returnType = method[i].getReturnType();    Class<?> para[] = method[i].getParameterTypes();    int temp = method[i].getModifiers();    System.out.print(Modifier.toString(temp) + " ");    System.out.print(returnType.getName() + "  ");    System.out.print(method[i].getName() + " ");    System.out.print("(");    for (int j = 0; j < para.length; ++j) {        System.out.print(para[j].getName() + " " + "arg" + j);        if (j < para.length - 1) {            System.out.print(",");        }    }    System.out.println(")");}//public java.lang.String  toString (java.lang.String arg0)//public int  size ()// void  eat (java.lang.String arg0)class A{    private int i1;    protected Integer i2;    int i3;    public String i4;    public double i5;    public A(){}    public int size(){return 0;}    void eat(String s){        System.out.println("eats");    }    public String toString(String name){        System.out.println(name+":A");        return name+"A";    }}

调用一个对象的方法

调用对象的方法和修改属性。即使属性是私有的,也可以修改。

Class classA = A.class;Method m1 = classA.getDeclaredMethod("eat",String.class);m1.invoke(classA.newInstance(), "rice");//eats riceA a = (A) classA.newInstance();Field i = classA.getDeclaredField("i1");i.setAccessible(true);i.set(a, 4);System.out.println(i.get(a)); //4class A{    private int i1;    public A(){}    void eat(String s){        System.out.println("eats "+s);    }}