概念:能够分析类能力的程序称为反射。反射机制在运行状态中对任何一个类都能够知道这个类的属性和方法;对于任何一个对象都可以调用到它的任何一个方法和属性。
作用:
- 在运行时分析类的能力
- 在运行时查看对象,例如,编写一个toString方法供所有类使用
- 实现通用的数组操作代码
- 利用method对象,这个对象很像c++中的函数指针
Class类
假设我们现在有一个Animal类
(一)获取Class对象的三种方式
- 直接通过对象名●getClass()获取 例如:
Animal an = new Animal(); Class cl = an.getClass();
-
通过class属性获取(任何一个数据类型,都有一个静态的class属性)
Class cl = Animal.class;
-
通过Class.forName()来获取(一般使用这种方式)
Class an; try { an = Class.forName("java20180723.Animal"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
(二)通过Class类进行实例化
Animal a = (Animal) an.newInstance();
利用反射获取类中方法和字段
(1)获取构造方法
这个方法能够获取共有构造器,不能获取其它的private和protected
在Animal类中,共有三个构造方法
public Animal() {
// TODO Auto-generated constructor stub
}
public Animal(String name){
}
public Animal(String name,Integer age){
}
我们尝试来获取它
Class an;
try {
an = Class.forName("java20180723.Animal");
Constructor[] cons = an.getConstructors();
for (Constructor con : cons) {
System.out.println(con.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
有三个构造方法,所以输出执行了三次
如果想获取它的私有构造器呢?
我们可以通过另一个方法,如下:
我们再试一下:
public static void main(String[] args) {
Class cl = new Animal().getClass();
try {
Constructor[] cons = cl.getDeclaredConstructors();
for (int i = 0; i < cons.length; i++) {
// cons[i].setAccessible(true);//表示允许方法私有方法
System.out.println(cons[i].getName());
}
} catch (Exception e) {
// TODO: handle exception
}
}
(2)获取普通公有方法
Class an;
try {
an = Class.forName("java20180723.Animal");
Method[] methods = an.getMethods();
for (Method m : methods) {
System.out.println(m.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
运行结果:
(该方法除了会获取到Animal里边的方法,还会获取到它的父类Object类的方法)
所以我们更常用的时getDeclaredFields()方法
它的API是这个样子的:
这个方法会获取当前类的所有方法
Class an;
try {
an = Class.forName("java20180723.Animal");
Method[] methods = an.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m.getName()+"返回值"+m.getReturnType());
}
} catch (Exception e) {
e.printStackTrace();
}
获取域值
Class an;
try {
an = Class.forName("java20180723.Animal");
Field[] fields = an.getDeclaredFields();
for (Field f:fields) {
System.out.println(f.getName());
}
} catch (Exception e) {
e.printStackTrace();
}