Java学习之反射

反射


在这里插入图片描述

【1】反射的定义:

运行期间可以获取对象的类型,类型的方法,类型的属性,类型的构造方法等,让对象可以认识到自身的结构。

【2】方法:

(1)获取对象的类型(获取类对象)

  • 方法1:Object.getClass()(返回类型包括类名包名等)
  • 方法2:Class.forName("类名)(和方法一的返回类型一致)
  • 方法3:类名.class()
    //反射
         //【1】获取对象的类型(类对象)
          //方法1:Objetc.getclass()
         System.out.println(new User().getClass());
         //class Reflect.User
         //方法2:Class.forName("类名");
         System.out.println(Class.forName("Reflect.User"));
         //抛异常//class Reflect.User
         //这里注意要填写的类名包括包名
         //放法3:类名.Class()
         System.out.println(User.class);
         //class Reflect.User
         //这里要注意的是,class不大写
    
         //注意:以上无论用哪种方式所获得的对象都是同一份信息,这个类型的信息 在JVM中仅存在一份
    
    

注意:以上无论用哪种方式所获得的对象都是同一份信息,这个类型的信息 在JVM中仅存在一份

(2)类对象的功能

功能1:用反射的方式来创建对象
方法:类对象.newInstance()

这里用一般正常创建对象的方式和用反射来创建对象两种方式做个对比,让读者能更清晰的来了解反射

//【2】类对象的功能
       //1:用反射的方式创建对象
       //首先是用正常的new 的方式来创建对象
       User user = new User();
       //用反射的方式,来创建对象 方法:类对象.newInstance();//创建一个新实例(新对象)
       User user1 = new User().getClass().newInstance();//抛异常
       System.out.println(user1);//Reflect.User@1540e19d
       User user2 = (User)Class.forName("Reflect.User").newInstance();
       System.out.println(user2);//Reflect.User@677327b6
       User user3 = User.class.newInstance();
       System.out.println(user3);//Reflect.User@14ae5a5
//        这里注意:用newInstance的时候有两个限制:A:要求类必须有空参构造
//                                           B:要求构造方法不能私有

这里注意:用newInstance的时候有两个限制:A:要求类必须有空参构造
B:要求构造方法不能私有

功能2:用反射的方式来获取方法信息
方法:
(1)类对象.getMethod();获取本类的所有公共方法(public),包括继承的。
(2)类对象.DeclaredMethods();获取本类的所有方法(包括private,protected,public)不包括继承的方法。
(3)类对象.Method(方法名,参数类型);找公共方法,包括继承的,注意==此处的参数类型要填(类型.class)==比如是String类型,就填String.class,没有参数的话,就不填。
(4)类对象.DeclaredMethod(方法名,参数类型);找本类的,不包括继承的方法。
              //2:用反射的方式来获取方法信息
        Method[] methods = User.class.getMethods();//返回的是User类中所有的公共方法,包括所继承的
        for (Method m: methods
             ) {
            System.out.println(m);
        }
        //运行结果:
//        public java.lang.String Reflect.User.getName()
//        public void Reflect.User.setName(java.lang.String)
//        public java.lang.String Reflect.User.getLocal()
//        public void Reflect.User.setAge(int)
//        public int Reflect.User.getAge()
//        public void Reflect.User.setLocal(java.lang.String)
//        public final void java.lang.Object.wait() throws java.lang.InterruptedException
//        public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//        public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//        public boolean java.lang.Object.equals(java.lang.Object)
//        public java.lang.String java.lang.Object.toString()
//        public native int java.lang.Object.hashCode()
//        public final native java.lang.Class java.lang.Object.getClass()
//        public final native void java.lang.Object.notify()
//        public final native void java.lang.Object.notifyAll()
        System.out.println("---------------------------------------");
        Method[] methods1 = User.class.getDeclaredMethods();//返回的是User类中所有的方法(包括private,protected,public),不包括所继承的
        for (Method m1:methods1
             ) {
            System.out.println(m1);
        }
        //运行结果:
//        public java.lang.String Reflect.User.getName()
//        public void Reflect.User.setName(java.lang.String)
//        public java.lang.String Reflect.User.getLocal()
//        public void Reflect.User.setAge(int)
//        public int Reflect.User.getAge()
//        public void Reflect.User.setLocal(java.lang.String)
        System.out.println("---------------------------------------");
        System.out.println(User.class.getMethod("getAge"));
        System.out.println(User.class.getDeclaredMethod("setLocal", String.class));
        //运行结果:
//        public int Reflect.User.getAge()
//        public void Reflect.User.setLocal(java.lang.String)

功能3 :用反射的方法获取属性信息
方法:
(1)类对象.getFields();//获取所有属性(包括继承的)
(2)类对象.getDeclaresField();//获取本类所有属性,不包括继承的
(3)类对象.getField(“属性名”);
(4)类对象.getDeclaredField(“属性名”);
//(1)类对象.getFields();//获取所有属性(包括继承的)
        Field[] fields = User.class.getFields();
        for (Field f:fields
             ) {
            System.out.println(f);
        }
        //(2)类对象.getDeclaresField();//获取本类所有属性,不包括继承的
        //(3)类对象.getField(“属性名”);
        //(4)类对象.getDeclaredField("属性名");
功能4:用反射的方法获取构造方法
方法:获取构造方法
(1)类对象.getConstractors();//获取所有的公共的构造方法
(2)类对象.getDeclaredConstractor();//获取本类的构造方法
(3)类对象.getConstractor(int.class);
(4)类方案.getDecclaredConstractor(int.class);
      Constructor<?>[] constructors = User.class.getConstructors();
      for (int i = 0; i < constructors.length; i++) {
          System.out.println("Constractors:"+constructors[i]);//所有的构造方法
          //Constractors:public Reflect.User()
          //Constractors:public Reflect.User(int)
      }
      Constructor<?>[] declaredConstructors = User.class.getDeclaredConstructors();
      for (int i = 0; i < declaredConstructors.length; i++) {
          System.out.println("DeclaredConstractors:"+declaredConstructors[i]);//本类内的构造
          //DeclaredConstractors:public Reflect.User()
          //DeclaredConstractors:public Reflect.User(int)
      }
      Constructor<User> constructor = User.class.getConstructor(int.class);
      System.out.println("Constractor:"+constructor);//Constractor:public Reflect.User(int)
      Constructor<User> declaredConstructor = User.class.getDeclaredConstructor(int.class);
      System.out.println("DeclaredConstractor:"+declaredConstructor);//DeclaredConstractor:public Reflect.User(int) 
功能5:用反射调用方法
正常调用方法:对象.方法名(参数)
反射调用方法:方法.invoke(对象.参数)
       User u = new User();
       Method getAge = User.class.getDeclaredMethod("getAge");
       getAge.setAccessible(true);//调用这个方法可以被访问,可以突破访修饰符的限制
       getAge.invoke(u);//抛异常//反射调用方法(性能较低)

       //反射调用public void setName(String name)
       Method setName = User.class.getDeclaredMethod("setName", String.class);
       setName.invoke(u,"张三");
       //反射调用私有构造
       Method getLocal = User.class.getDeclaredMethod("getLocal");
       getLocal.setAccessible(true);
       getLocal.invoke(u);
       //反射调用构造方法
       Constructor<Student> dc1 = Student.class.getDeclaredConstructor();
       dc1.setAccessible(true);
       Student stu = dc1.newInstance();
       System.out.println(stu);
       //Reflect.Student@135fbaa4

这里 反射调用的是invoke()方法,

缺点是和正常的调用方法相比反射调用性能低,调用复杂
优点是可以调用私有方法,突破正常的方法限制
其中如果要调用private 修饰的私有方法时,要在invoke语句之前加上方法.setAccessibls(),如果参数写true 代表可以访问,false 代表不可以访问。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值