反射基础
正文
才敲出来的代码被机器执行要经历保存到.java文件中、编译.java文件为.class文件、jvm将class文件通过类加载器加载进入内存这三个步骤。
.class文件在内存中以Class类的结构表示。当获得Class类以后就可以获得.class文件的所有内容,即属性、一般方法、构造方法。具体是这样:
- Field 属性类
- Constructor 构造方法类
- Method 普通方法类
现在假设我有这样一个类通过反射有三种方式可以得到Person的Class实例,具体代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class 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;
}
}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,无参构造
然后可用class
的newInstance
方法进行实例化,注意类型转换就好1
Person p=(Person) cP3.newInstance();
有参构造
与无参构造不同的是,有参时需要先得到Constructor的实例。可以通过cp3的getConstrutor方法获得,其中的参数为所要使用参数的构造方法的数据类型.class,如:而后就可创建Person实例1
Constructor cs=cP3.getConstrutor(String.class,int.class);
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 | Person p=cP3.newInstance(); |
其它
今天还了解了下枚举、可变参数和泛型。
枚举是简化的构造方法私有类
可变参数只能用于形参的位置,其它位置不可用,可变参数只能位于形参的最后,所以一个方法只能有一个可变参数。它的结构大致形如:
1 | public void FunctionName(int ...arr){} |
泛型不知道如何总结