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入门到精通教程
查看: 393|回复: 0

[Java反射学习]深入浅出JAVA的反射机制

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

    [LV.1]初来乍到

    发表于 2014-10-29 23:57:49 | 显示全部楼层 |阅读模式
    java 运行时 环境中,对于任意一个类,能否知道这个类有哪些属性和方法?
         对于任意一个对象,能否调用他的方法?这些答案是肯定的,这种动态获取类的信息,以及动态调用类的方法的功能来源于JAVA的反射。从而使java具有动态语言的特性。 JAVA反射机制主要提供了以下功能:
    1.在运行时判断任意一个对象所属的类
    2.在运行时构造任意一个类的对象
    3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
    4.在运行时调用任意一个对象的方法(*****注意:前提都是在运行时,而不是在编译时) Java 反射相关的API简介:
    位于java.lang.reflect包中
    --Class类:代表一个类
    --Filed类:代表类的成员变量
    --Method类:代表类的方法
    --Constructor类:代表类的构造方法
    --Array类:提供了动态创建数组,以及访问数组的元素的静态方法。该类中的所有方法都是静态方法 Class类      在 java 的Object类中的申明了数个应该在所有的java类中被改写的methods:hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()返回一个Class 类型的对象。
          Class类十分的特殊,它和一般的类一样继承自Object,其实体用以表达java程序运行时的class和 interface,也用来表达 enum,array,primitive,Java Types 以及关键字void,当加载一个类,或者当加载器(class loader)的defineClass()被JVM调用,便产生一个Class对象,Class是Reflection起源,针对任何你想探勘的class(类),唯有现为他产生一个Class的对象,接下来才能经由后者唤起为数十多个的反射API。 Java允许我们从多种途径为一个类class生成对应的Class对象 --运用getClass():Object类中的方法,每个类都拥有此方法
       例:String str="abc";
             Class cl=str.getClass(); --运用 Class.getSuperclass():Class类中的方法,返回该Class的父类的Class
    --运用 Class.forName()静态方法:
    --运用 .Class:类名.class
    --运用 primitive wrapper classes的TYPE语法: 基本类型包装类的TYPE,如:Integer.TYPE
       注意:TYPE的使用,只适合原生(基本)数据类型。 运行时生成instance      想生成对象的实体,在反射动态机制中有两种方法,一个针对无变量的构造方法,一个针对带参数的构造方法,如果想调用带参数的构造方法,就比较的麻烦,不能直接调用Class类中的newInstance(),而是调用Constructor类中newInstance()方法,首先准备一个Class[]作为Constructor的参数类型。然后调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,最后再准备一个Object[]作为Constructor对象昂的newInstance()方法的实参。
           在这里需要说明的是 只有两个类拥有newInstance()方法,分别是Class类和Constructor类Class类中的newInstance()方法是不带参数的,而Constructro类中的newInstance()方法是带参数的需要提供必要的参数。  
       
        Class c=Class.forName("DynTest");
    Class[] ptype=new Class[]{double.class,int.class};
    Constructor ctor=c.getConstructor(ptypr);
    Object[] obj=new Object[]{new Double(3.1415),new Integer(123)};
    Object object=ctor.newInstance(obj);
    System.out.println(object);
                              
       

    运行时调用Method

            这个动作首先准备一个Class[]{}作为getMethod(String name,Class[])方法的参数类型,接下来准备一个Obeject[]放置自变量,然后调用Method对象的invoke(Object obj,Object[])方法。
        运行时调用Field内容
            变更Field不需要参数和自变量,首先调用Class的getField()并指定field名称,获得特定的Field对象后便可以直接调用Field的 get(Object obj)和set(Object obj,Object value)方法。
         package cn.com.reflection;   
      
    import java.lang.reflect.Field;   
    import java.lang.reflect.InvocationTargetException;   
    import java.lang.reflect.Method;   
      
    public class ReflectTester {   
      
        /**  
         * 在这个类里面存在有copy()方法,根据指定的方法的参数去 构造一个新的对象的拷贝  
         * 并将他返回  
         * @throws NoSuchMethodException   
         * @throws InvocationTargetException   
         * @throws IllegalAccessException   
         * @throws InstantiationException   
         * @throws SecurityException   
         * @throws IllegalArgumentException   
         */  
        public Object copy(Object obj) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{   
               
            //获得对象的类型   
            Class classType=obj.getClass();   
            System.out.println("该对象的类型是:"+classType.toString());   
               
            //通过默认构造方法去创建一个新的对象,getConstructor的视其参数决定调用哪个构造方法   
            Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});   
               
            //获得对象的所有属性   
            Field[] fields=classType.getDeclaredFields();   
               
            for(int i=0;i< fields.length;i++){
                //获取数组中对应的属性   
                Field field=fields;               
                String fieldName=field.getName();   
                String stringLetter=fieldName.substring(0, 1).toUpperCase();   
                   
                //获得相应属性的getXXX和setXXX方法名称   
                String getName="get"+stringLetter+fieldName.substring(1);   
                String setName="set"+stringLetter+fieldName.substring(1);   
                   
                //获取相应的方法   
                Method getMethod=classType.getMethod(getName, new Class[]{});   
                Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});   
                   
                //调用源对象的getXXX()方法   
                Object value=getMethod.invoke(obj, new Object[]{});   
                System.out.println(fieldName+" :"+value);   
                   
                //调用拷贝对象的setXXX()方法   
                setMethod.invoke(objectCopy,new Object[]{value});                                
            }              
            return objectCopy;              
        }         
          
        public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {   
            Customer customer=new Customer();   
            customer.setName("hejianjie");   
            customer.setId(new Long(1234));   
            customer.setAge(19);              
            Customer customer2=null;   
            customer2=(Customer)new ReflectTester().copy(customer);   
            System.out.println(customer.getName()+" "+customer2.getAge()+" "+customer2.getId());              
            System.out.println(customer);   
            System.out.println(customer2);            
        }   
    }   
       
    class Customer{         
        private Long id;         
        private String name;         
        private int age;
                   
        public Customer(){              
        }   
      
        public int getAge() {   
            return age;   
        }     
      
        public void setAge(int age) {   
            this.age = age;   
        }     
      
        public Long getId() {   
            return id;   
        }     
      
        public void setId(Long id) {   
            this.id = id;   
        }     
      
        public String getName() {   
            return name;   
        }     
      
        public void setName(String name) {   
            this.name = name;   
        }         
    }     


    package cn.com.reflection;   
      
    import java.lang.reflect.Array;   
      
    public class ArrayTester1 {     
        /**  
         * 此类根据反射来创建  
         * 一个动态的数组   
         */  
        public static void main(String[] args) throws ClassNotFoundException {              
            Class classType=Class.forName("java.lang.String");              
            Object array= Array.newInstance(classType,10);  //指定数组的类型和大小              
             //对索引为5的位置进行赋值   
            Array.set(array, 5, "hello");              
            String s=(String)Array.get(array, 5);              
            System.out.println(s);              
               
            //循环遍历这个动态数组   
            for(int i=0;i<((String[])array).length;i++){                  
                String str=(String)Array.get(array, i);                 
                System.out.println(str);   
            }     
        }     
    }   
       
         
       

         
          
          
            
            

             
            

             
            
          
         
       

       
      


    源码下载:http://file.javaxxz.com/2014/10/29/235749250.zip
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-19 08:18 , Processed in 0.398620 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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