java反射

2020-04-13  本文已影响0人  柳橙汁柳子

1.反射是java被视为动态语言的关键。

(动态语言:python,c#;静态:c/c++)

优点:实现动态创建对象和编译,体现出很大的灵活性;

缺点:对性能有影响。

2.Class类(注意区分Class和class和.class文件)

i.一个类在内存中只有一个Class对象,一个类被加载后,整个结构都会被封装在Class对象中;

ii.每个对象都记得是哪个类创建了自己,可以通过任何一个对象 反射出该对象的类;

iii.Class类的对象由系统创建,每个Class对象 对应一个被加载的 .class文件;

iv.获取Class对象的方法:

a) 已知具体类,通过类的class属性(最安全,性能最高):

Class c1 = Person.class;

b) 已知目标类的实例,通过调用该实例的getClass()方法:

Person person = new Person();
Class c2 = person.getClass();

c) 已知类的完整路径,通过Class类的静态方法forName()获得:

Class c3 = Class.forName("com.test.Person");

*注:以上c1、c2、c3实际上是同一个对象
d) 基本内置类型的包装类 都有一个TYPE属性:

Class c4 = Integer.TYPE;

e)利用ClassLoader:


v.哪些东西拥有Class对象?
类(外部类、内部类)、接口、数组(注意维度一样的数组则是同一个Class对象,否则不是,例如一维数组和二维数组不是同一Class对象)、枚举、注解、基本数据类型、void。

3.获取类的运行时结构

获取User类的Class对象:

Class c1 = Class.forName("com.test.User");

获取User类的名字:

c1.getName();
c1.getSimpleName();

获得User类的属性:

c1.getFields();
c1.getFields("name");
c1.getDeclaredFields(); // 获取包括private的全部属性
c1.getDeclaredFields("name");

获得类的方法:

c1.getMethods(); // 获得该类和父类的所有public方法
c1.getMethods("name");
c1.getDeclaredMethods();
c1.getDeclaredMethods("name"); // 还可以指定参数

获得类构造器

c1.getConstructors();
c1.getDeclaredConstructors();

有了Class对象,能干什么?

4.通过反射动态地创建对象:

Class c1 = Class.forName("com.test.User");
User user1 = (User)c1.newInstance(); // 本质上是调用了类的无参构造器

// 通过有参构造器创建对象
Constructor constructor = 
c1.getDeclaredConstructors(String.class, int.class, int.class);
User user2 = (User)constructor.newInstance("柳子", 1, 18);

// 通过反射调用普通方法
User user3 = (User)c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(user3, "柳子2");

// 通过反射操作属性
User user4 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
name.setAccessible(true); // 设置私有属性修改权限(会提高效率)
name.set(user4, "柳子3");

// 通过反射获取泛型

// 通过反射获得注解(很多框架用到)
上一篇下一篇

猜你喜欢

热点阅读