Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI,它假定我们在编译时已经知道了所有的类型信息;另一种是反射机制,它允许我们在运行时发现和使用类的信息。

 

为什么要用反射

  1. 在传统方式中创建对象的方法:new
    前提是必须知道要使用的类,同时如果要修改使用的类,必须修改源码。
  2. 问题:
    2.1如果无法确定要执行的对象怎么办?
    2.2如果要修改使用的类,必须修改源码.这在实际项目中极其不方便,因为必须重新在服务器上上传项目文件。
  3. 问题的解决:使用反射。

反射的概念和作用:

1.反射的概念: 万事万物皆对象,类也是对象.
类的相同特征是都具有:属性,方法,构造器 在java中有一个类Class,该类封存了任何一个类的相关信息,即Class对象存储了一个类的信息,可以通过Class对象来创建目标类对象
因此,我们通过反射创建类对象和使用类对象.
2. 反射的作用:动态创建对象(就像一面镜子,照出了其他类的信息。)
3. 反射的缺点:效率低,影响程序性能。

 

反射的使用

三种方式

 

1

Class.forName();//根据全限定路径获取(常用)

Class cla01=Class.forName(“com.dayunwu.pojo.Person”);

2

对象名.getClass();//根据对象获取(比较鸡肋)

Class cla03=new Person().getClass();

 

3

类名.class//根据类名获取`(更鸡肋,我都知道了类名了还用反射?)

 

Class cla02=Person.class;

 

 

通过反射操作属性

 

</pre>
<pre>//获取类对象
Class cla = Class.forName("com.dayunwu.pojo.Student");
//获取反射类属性
//获取类及其父类的公共字段
Field[] fds = cla.getFields();
for (Field f : fds) {
    System.out.println("获取属性名------>" + f.getName());
    System.out.println("获取修饰符------>" + f.getModifiers());
    System.out.println("获取类型------>" + f.getType());//返回的是类型的Class对象
}
System.out.println("******************************");
//获取类声明的所有字段
Field[] fds2 = cla.getDeclaredFields();
for (Field f : fds2) {
    System.out.println("获取属性名----->" + f.getName());
    System.out.println("获取修饰符------>" + f.getModifiers());
    System.out.println("获取类型------>" + f.getType());//返回的是类型的Class对象
}
System.out.println("******************************");
//获取指定的字段
Field f = cla.getField("pname");//指定获取类及其父类的公共字段
System.out.println(f.getName());
Field f2 = cla.getDeclaredField("money");//指定获取类的所有字段
System.out.println(f2.getName());
Field f3 = cla.getSuperclass().getDeclaredField("pname");//指定获取父类声明的字段
System.out.println(f3.getName());
//操作字段值
System.out.println("************操作静态字段**********************");
//操作静态属性
Field fs = cla.getDeclaredField("money");
fs.set(null, 2000);
System.out.println(fs.get(null));
System.out.println("************操作非静态字段**********************");
//操作非静态属性
Field fd = cla.getDeclaredField("sname");
Object obj = cla.newInstance();
fd.set(obj, "张三");
System.out.println(fd.get(obj));
//反射操作私有化属性(暴力)
Field fd2 = cla.getDeclaredField("ssex");
fd2.setAccessible(true);//暴力反射,操作私有化属性,一般不使用,破坏了封装
Object obj2 = cla.newInstance();//获取实例化对象
System.out.println(fd2.get(obj2));</pre>
<pre>