Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 340|回复: 0

[Java反射学习]Java内省和反射机制三步曲之(2)反射

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-28 23:56:29 | 显示全部楼层 |阅读模式
    经过多方面的资料搜集整理,写下了这篇文章,本文主要讲解java的反射和内省机制,希望对大家有点帮助,也希望大家提出不同的看法! 1).通俗的讲,反射就是把java类中的各种成分映射成相应的java类.如一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个的java类表示。那么java类的Class类显然要提供一系列的方法来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的类的实例对象来表示,它们是Field,Method,Construtor,Package等。 JAVA反射机制是在运行状态中, 对于任意一个类,都能够得到这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法; 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.
      2).一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。
      
       
       
         
       

         
       
      
    3).Constructor类:Constructor类代表某个类中的一个构造方法.

    .1)得到某个类所有的构造方法:例如: Constructor[] cons = String.class.getConstructors();

    .2)得到某一个构造方法:例如: Constructor cons = String.class.getConstructor(StringBuffer.class);//获得构造方法时要调用的参数类型,因为要识别构造方法,必须靠参数类型。

    .3)创建实例对象:
    通常情况下:String str = new String(new StringBuffer("abc"));
    反射方式: String str = (String) cons.newInstance(new StringBuffer("abc"));//调用获得方法时要用到上面相同类型的实例对象

    .4)Class.newInstance()方法,它是把class - constructor - new obj 简化为 class - newInstance
    原理:该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象,该方法内部用到了缓存机制来保持默认构造方法的实例对象,相当于调用 无参的构造方法,反射会导致系统性能下降.所以使用反射要慎重。
    例如: String sr = String.class.newInstance();

    相关代码:
      
      
       
       
        public static void main(String[] args) throws Exception {   
            Constructor constructor = String.class.getConstructor(StringBuffer.class);   
            String str2 =(String)constructor.newInstance(new StringBuffer("abc"));   
            //newInstance()返回的是一个Object,所以要用类型转换   
            System.out.println(str2);   
                
            String str3 = (String)constructor.newInstance("abc");   
            System.out.println(str3);//有异常:argument type mismatch   
            //获得构造方法时要调用的参数类型和调用获得方法时要有相同的参数类型   
        }   
       
       
      


    4).Field类:Field类代表类中的一个成员变量
    相关代码一:

      
       
       
        public class Point {   
        public Integer x;   
        private Integer y;   
          
        public Point(Integer x, Integer y) {   
            super();   
            this.x = x;   
            this.y = y;   
        }   
        }   
          
        public static void main(String[] args) throws Exception {   
            Point reflect = new Point(2, 5);   
            Field fieldX = Point.class.getField("x");   
            // 此时fieldX的值不是5,fieldX不是对象身上的变量,而是类上,要用它去取对象身上的值,必须和实例对象结合使用。   
          
            Integer valueX = (Integer) fieldX.get(reflect);   
            System.out.println(valueX);// 2   
          
        //    Field fieldY = Point.class.getField("y");   
        //    // 由于属性y的修饰符是private,所以程序运行到此处就有异常,说该属性不存在:java.lang.NoSuchFieldException: y   
        //    Integer valueY = (Integer) fieldY.get(reflect);   
          
        //    // 下面的方法可以解决无法查看私有属性的方法   
        //     Field fieldY2 = Point.class.getDeclaredField("y");   
        //    //getDeclaredField():只要声明的变量都可以查看,运行到此处无异常   
        //     Integer valueY2 = (Integer) fieldY2.get(reflect);   
        //    // 在这里会有异常,属性虽然存在,但无法访问:Class com.sun.Reflect can not access a member of class com.sun.Point with modifiers "private"   
          
          
            // 暴力反射,即使设为private的属性变量依然可以访问,   
            Field fieldY3 = Point.class.getDeclaredField("y");   
            fieldY3.setAccessible(true);   
            Integer valueY3 = (Integer) fieldY3.get(reflect);   
            System.out.println(valueY3);// 5     
            //一个代表看不见,一个代表看见了但取出到值,就类如:(一)我看不到别人的钱,(二)是我看到了,但是用不到,暴力反射就相当于"抢劫".   
        }   
          
        相关代码二:   
        public class Point {   
        public String str1 = "who";   
        public String str2 = "when";   
        public String str3 = "where";   
        public Integer num = 5;   
        public boolean istrue = true;   
          
        public String toString() {   
            return str1 + "-" + str2 + "-" + str3 + "-" + num + "-" + istrue;   
        }   
        }   
          
        public class Reflect {   
        public static void main(String[] args) throws Exception {   
            Point point = new Point();   
            System.out.println(point);// who-when-where-5-true   
            changeFieldValues(point);   
            System.out.println(point);// Who-When-Where-5-true:把"w"改成了大写的"W"   
            //我们看到了反射可以任意改变属性的值,这种应用在很多框架中都有使用!   
        }   
          
        private static void changeFieldValues(Point point) throws IllegalAccessException {   
            Field[] fields = Point.class.getFields();   
            for (Field field : fields) {   
              if (field.getType() == String.class) {   
                String oldVal = (String) field.get(point);   
                String newVal = oldVal.replace("w", "W");   
                field.set(point, newVal);   
              }   
            }   
        }   
        }   
          
       
       
      


    5).Method:Method类代表某个类中的一个方法;
    .1)得到某个类中某一个方法:例如:Method stringCharAt = String.class.getMethod("charAt", int.class);
    .2)创建实例对象:
    通常方式: System.out.println("abcd".charAt(1));
    反射方式: System.out.println(stringCharAt.invoke("abcd", 1));//b,如果invoke得第一个参数为空,那么该method对应的是一个静态方法
    .3)invoke()在JDK1.4,和1.5中的参数形式不同。
    相关代码:


      
       
       
        public static void main(String[] args) throws Exception {   
            String str = "welcome!";   
            Method charAt = String.class.getMethod("charAt", int.class);   
            System.out.println(charAt.invoke(str, 0));// w   
        }   
       
       
      
      
       
       
      


      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 01:57 , Processed in 0.358041 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表