Java反射的简单使用

来源:互联网 发布:广东省工商局网络培训 编辑:程序博客网 时间:2024/06/05 18:13

举个栗子通俗说下反射的用途

类是对万物的抽象,黑人白人黄种人,但是都有相似的属性(头发,四肢,耳朵,眼睛等),所以可以抽象成一个类(Person类),奔驰宝马大众都有发动机,车架,车轮属性可以组成一个类(Car类),猫狗猪可以组成一个类(Animal类)

这三个类有没有相似的属性呢?都有属性和行为,对,都有属性和行为的类可以抽象成一个类上类(Class类)

所以类是对万物的抽象,而Class类是对类的抽象

我们使用对象是为了拿到类的属性值或者执行类中方法,那么我们使用反射就是为了拿到属性的名字和方法名也就是属性的属性,获取类的信息。

以下图的Person类为例:

Person person = new Person(“liangchaojie”,”btbu”);
Class c = person.getClass();
或者
Class c = Class.forName(“demo1.Person”);

这里写图片描述

1 类名

c.getName()

注意获取的类名是demo1.Person而不是Person

2 构造方法

Constructor[] fs = c.getDeclaredConstructors();

注意构造器的名字是demo1.Person而不是Person

3 属性

Field[] f = c.getDeclaredFields();

注意getDeclaredFields()与getFields()区别是前者是获取所有的属性(无论是private还是public都可以获取),后者只能获取public的属性(其他访问属性都不可以)

4 获取属性的数据类型

field.getType()

注意返回类型是class java.lang.String,int而不是String 和int

5 获取属性/方法的访问修饰符

field.getModifiers()

注意 :虽然方法名有s但是返回的是一个int值,为什么要加s?因为修饰符可能不止一个,如果不止一个就将所有的修饰符对应的数值求和返回

1 表示public
2表示private
4表示protected
8表示static
16表示final
32表示SYNCHRONIZED
64表示VOLATILE
128表示TRANSIENT
256表示NATIVE
512表示INTERFACE
1024表示abstract
2048表示STRICT
(后面的修饰符是隐藏的,我们使用“.”是”.”不出来的)

java中还有其他的修饰符,如下图所示:

这里写图片描述

举例:public static final = 1+8+16=25
所以对于一个类中的静态常量来说,其修饰符返回值是25

6 方法

Method[] f= c.getDeclaredMethods();

7 给属性赋值

Field m = fs[i];
m.setAccessible(true);
m.set(person,”haha”);

这里写图片描述

8 调用类的方法

Method m = fs[i];
m.setAccessible(true);
if(m.getName().contains(“set”)){
m.invoke(person, “lcj”);
}

9 接下来我们把Person类修改下

这里写图片描述

如何获取Person类的父类或者父接口呢?

Type[] interfaces = Class.forName(“demo1.Person”).getInterfaces();

Class s = Class.forName(“demo1.Person”).getSuperclass();

注意这里获取的接口或者类名都是“包名.类名/接口名”

10 假如Person类是一个空的类呢?

public class Person {}

这个时候获取该类的构造器,属性,和方法会是什么效果呢?

全部采用xxDeclaredxx方法

这里写图片描述

该类默认具有1个access$super方法,2个构造器,2个属性