Java中的反射(1,获取类对象,操作属性)

为什么要用反射

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

反射的概念和作用:

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

反射的使用

  1. 反射获取类对象的三种方式:
 Class.forName();//根据全限定路径获取(常用)
  对象名.getClass();//根据对象获取(比较鸡肋)
  类名.class//根据类名获取`(更鸡肋,我都知道了类名了还用反射?)

2.代码


              //第一种方式--->创建类对象(常用来创建对象)
                 Class cla01=Class.forName("com.dayunwu.pojo.Person");
              //第二种方式---->调用底层使用反射封装的方法(常用在方法的传参中)
                    Class cla02=Person.class;
              //第三种方式---->调用底层使用反射封装的方法(常用在方法的传参中)
                        Class cla03=new Person().getClass();

3.常用的方法:

    System.out.println("获取类对象的包名---->"+cla01.getPackage());
    System.out.println("获取类的修饰符----->"+cla01.getModifiers());
    System.out.println("获取类的名称(全限定路径,连包都获取)----->"+cla01.getName());
   System.out.println("获取类的名称(类名)----->"+cla01.getSimpleName());
   System.out.println("获取类的父类的类对象----->"+cla01.getSuperclass());    
  1. 通过反射操作属性:

*    获取类属性
    getFields()    //获取所有的公共(public)字段包括父类       返回Field[]数组
   getDeclaredFields()  // 获取所有声明的字段(不包括父类)       返回Field[]
     getField(String name) //  获取指定的公共字段包括父类       返回Field
    getDeclaredField(String name)   // 获取指定的声明的字段(不包括父类)                返回Field
*     操作类属性
**     操作静态属性
           类属性对象.get(null)              //返回静态属性的值
           类属性对象.set(null,"值")                //赋值
**    操作非静态属性
          类属性对象.get(Object obj);
          类属性对象.set(Object obj,"值");

代码:

   public static void operField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
               //获取类对象
      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));
       }
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页