反射基础

正文

才敲出来的代码被机器执行要经历保存到.java文件中、编译.java文件为.class文件、jvm将class文件通过类加载器加载进入内存这三个步骤。

.class文件在内存中以Class类的结构表示。当获得Class类以后就可以获得.class文件的所有内容,即属性、一般方法、构造方法。具体是这样:

  • Field 属性类
  • Constructor 构造方法类
  • Method 普通方法类
    现在假设我有这样一个类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class Person{
    private String name;
    private int age;

    public Person(){
    super();
    }
    public Person(String name,int agr){
    this.name=name;
    this.age=age;
    }
    public void setName(String name){
    this.name=name;
    }
    Piublic String getName(){
    return name;
    }
    public void setAge(int age){
    this.age=age;
    }
    Piublic int getAge(){
    return age;
    }
    }
    通过反射有三种方式可以得到Person的Class实例,具体代码如下:
    1
    2
    3
    4
    5
    6
    //1.通过类名.class获得
    Class cP1=Person.class;
    //2.通过对象.getClass()获取
    Class cP2=new Person().getClass();
    //3.使用路径获得(据说比较常用)
    Class cP3=Class.forName("路径");

    调用构造方法

    反射的方式可以不用new关键字创建对象,包括有参和无参两类。相同的是在创建对象前都需要得到class类的实例,也就是cP3,

    无参构造

    然后可用classnewInstance方法进行实例化,注意类型转换就好
    1
    Person p=(Person) cP3.newInstance();

    有参构造

    与无参构造不同的是,有参时需要先得到Constructor的实例。可以通过cp3的getConstrutor方法获得,其中的参数为所要使用参数的构造方法的数据类型.class,如:
    1
    Constructor cs=cP3.getConstrutor(String.class,int.class);
    而后就可创建Person实例
    1
    Person p=(Person) cP3.newInstance("whoAreYou",65535);

    设置属性

    以下代码是更改name属性的案例
    1
    2
    3
    4
    5
    6
    7
    8
    //实例化Person
    Person p=cP3.newInstance();
    //得到属性类
    Field f=c.getDeclaredField("name");
    //设置可以操作私有属性,如果没有则会报异常 IllegalAccessException
    f.setAccessible(true);
    //设置属性
    field.set(p,"Tom");

调用普通方法

这个调用普通方法的演示是用setName方法

1
2
3
4
5
6
7
8
Person p=cP3.newInstance();
Method setName=cP3.getMethod("setName",String.class)//得到Method
//执行
setName.invoke(p,"whoAreYou");
/*
*如果执行的方法为静态方法,则执行不需要对象。所有代码应该改为如下:
*setName.invoke(null,"whoAreYou");
*/

其它

今天还了解了下枚举、可变参数和泛型。
枚举是简化的构造方法私有类
可变参数只能用于形参的位置,其它位置不可用,可变参数只能位于形参的最后,所以一个方法只能有一个可变参数。它的结构大致形如:

1
public void FunctionName(int ...arr){}

泛型不知道如何总结