• JavaReflection(转载)


        平时看代码时,总是碰到这些即熟悉又陌生的名次,每天都与他们相见,但见面后又似曾没有任何的交集,所以今天我就来认识下这两个江湖侠客的背景:

    CLASS

        在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息
    获取Class实例的三种方式:
        (1)利用对象调用getClass()方法获取该对象的Class实例;
        (2)使用Class类的静态方法forName(),用类的名字获取一个Class实例(staticClass forName(String className) Returns the Classobject associated with the class or interface with the given stringname. );
        (3)运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
        在newInstance()调用类中缺省的构造方法 ObjectnewInstance()(可在不知该类的名字的时候,常见这个类的实例) Creates a new instance of the class represented by this Classobject.
        在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象

        Class对象的生成方式如下:

        1.Class.forName("类名字符串") (注意:类名字符串必须是全称,包名+类名);
        2.类名.class;
        3.实例对象.getClass();

    [html]
    package baseJava
     
    public class TestClass { 
     
        /** 
         * @param args 
         * 2013-4-11 上午10:30:05 
         * @author zhao_xingcai 
         */ 
        public static void main(String[] args) { 
            // TODO Auto-generated method stub 
            try { 
             
                //测试Class.forName()   
                Class classForName = Class.forName("baseJava.TestClass"); 
                System.out.println("classForName  : [" + classForName + "]"); 
                 
                //测试类名.class 
                Class classForName2 = TestClass.class; 
                System.out.println("classForName2 : [" + classForName2 + "]"); 
                 
                //测试Object.getClass()  
                TestClass newInstance = new TestClass(); 
                System.out.println("newInstance   : [" + newInstance.getClass() + "]"); 
                 
                //hashCode指的是内存的地址 
                System.out.println("newInstanceHashCode   : [" + newInstance.hashCode() + "]"); 
                 
                //toString代表该对象的一个字符串 
                //格式:this.getClass().getName() + '@' + Integer.toHexString(hashCode()) 
                System.out.println("newInstanceToString   : [" + newInstance.toString() + "]"); 
                 
                 
            }catch (ClassNotFoundException e) { 
                e.printStackTrace(); 
            } 
        } 
        /* 
         * 构造函数 
         */ 
        public TestClass() { 
            System.out.println(" 构造函数"); 
        } 
         
        /* 
         * 静态的参数初始化   
         */ 
        static { 
            System.out.println("静态的参数初始化  "); 
        } 
         
        /* 
         * 非静态的参数初始化   
         */ 
        { 
            System.out.println("非静态的参数初始化  "); 
        } 
     

    package baseJava;

    public class TestClass {

     /**
      * @param args
      * 2013-4-11 上午10:30:05
      * @author zhao_xingcai
      */
     public static void main(String[] args) {
      // TODO Auto-generated method stub
      try {
      
       //测试Class.forName() 
       Class classForName = Class.forName("baseJava.TestClass");
       System.out.println("classForName  : [" + classForName + "]");
       
       //测试类名.class
       Class classForName2 = TestClass.class;
       System.out.println("classForName2 : [" + classForName2 + "]");
       
       //测试Object.getClass()
       TestClass newInstance = new TestClass();
       System.out.println("newInstance   : [" + newInstance.getClass() + "]");
       
       //hashCode指的是内存的地址
       System.out.println("newInstanceHashCode   : [" + newInstance.hashCode() + "]");
       
       //toString代表该对象的一个字符串
       //格式:this.getClass().getName() + '@' + Integer.toHexString(hashCode())
       System.out.println("newInstanceToString   : [" + newInstance.toString() + "]");
       
       
      }catch (ClassNotFoundException e) {
       e.printStackTrace();
      }
     }
     /*
      * 构造函数
      */
     public TestClass() {
      System.out.println(" 构造函数");
     }
     
     /*
      * 静态的参数初始化 
      */
     static {
      System.out.println("静态的参数初始化  ");
     }
     
     /*
      * 非静态的参数初始化 
      */
     {
      System.out.println("非静态的参数初始化  ");
     }

    }


    运行结果如下:

    静态的参数初始化 
    classForName  : [class baseJava.TestClass]
    classForName2 : [class baseJava.TestClass]
    非静态的参数初始化 
     构造函数
    newInstance   : [class baseJava.TestClass]
    newInstanceHashCode   : [12677476]
    newInstanceToString   : [baseJava.TestClass@c17164]

        也就是说:

        三种方法生成CLASS对象是一样的,因为CLASS在JVM的名称是一样的,但是三种生成的方法略有不同:静态的方法属性初始化,是在加载类的时候初始化。而非静态方法属性初始化,是new类实例对象的时候加载。当我们编写一个新的JAVA类时,JVM就会帮我们编译成CLASS对象,存放在同名的.class文件中,在运行时,当需要生成这个类的对象时,JVM就会检查此类是否装载到内存中,会没有装载,就把.class装载到内存中,若装载过,则根据.class生成对象。

    OBJECT对象

        在Java中有这样一个类,它是所有类的祖先,任何类都是其子孙类,它就是java.lang.Object,如果一个类没有显式地指明其父类,那么它的父类就是Object。如同我们称自己为炎黄子孙一样,所有的类都可以称为Object子孙,^_^。在java中除了基本型别(数字、字符、布尔值,primitive type)不是对象之外,其它的均为对象(class type)。那么,这个Object到底给我们留下了什么“遗产”呢?下面将从最基本的讲起:

        1.  public boolean equals(Object obj).

        所有的类均可以按照自己的需要对equals方法进行覆盖,顾名思义,这个方法可用来比较两个对象是否“相等”,至于什么才叫“相等”,各个类可以根据自己的情况与需要自行定义。例如String,就是要求两个对象所代表的字符串值相等,而对于一个雇员类(Employee),则可能是要求姓名、年龄、工资等一样才算是“相等”。尽管不同的类有不同的规则,但是有一条规则却是公用的,它就是:如果两个对象是“一样”(identical)的,那么它们必然是“相等”(equals)的。那么什么才叫“一样”?如果a==b,我们就说a和b是“一样的”,即a和b指向(refer to)同一个对象。Object类中的equals方法实施的就是这一条比较原则,对任意非空的指引值a和b,当且仅当a和b指向同一个对象时才返回true。

        2.  public int hashCode()

        每个类都可以复写Object类中的hashCode方法,Object类中的hashCode方法就是简单

    地将对象在内存中的地址转换成int返回。这样,如果一个类没有复写hashCode方法,那么它的hashCode方法就是简单地返回对象在内存中的地址。在JDK中,对hashCode也定义了一系列约束,其中有一条就是如果两个对象是“equal”的,那么它们的hashCode方法返回的整数值必须相同,但是如果两个对象是“unequal”,那么hashCode方法的返回值不一定必须不同。正因为这个约束,我们如果复写了equals()方法,一般也要复写hashCode方法。
        3.public String toString()

        toString方法是一个从字面上就容易理解的方法,它的功能是得到一个能够代表该对象的一个字符串,Object类中的toString方法就是得到这样的一个字符串:this.getClass().getName() + '@' + Integer.toHexString(hashCode()),各个类可以根据自己的实际情况对其进行改写。

    JAVA的反射机制

        JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
        Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    [html]
    package baseJava; 
     
    import java.lang.reflect.Array; 
    import java.lang.reflect.Constructor; 
    import java.lang.reflect.Field; 
    import java.lang.reflect.Method; 
     
    public class Reflect { 
     
        /** 
         * @param args 
         *            2013-4-11 上午11:20:59 
         * @author zhao_xingcai 
         */ 
        public static void main(String[] args) { 
            // TODO Auto-generated method stub 
             
     
        } 
         
        /** 
         * 得到某个对象的属性 
         * @param owner 
         * @param fieldName 
         * @return 
         * @throws Exception 
         * 2013-4-11 上午11:25:48 
         * @author zhao_xingcai 
         */ 
        @SuppressWarnings("unchecked") 
        public Object getProperty(Object owner, String fieldName) throws Exception { 
            //得到该对象的Class 
            Class ownerClass = owner.getClass(); 
            //通过Class得到类声明的属性 
            Field field = ownerClass.getField(fieldName); 
            //通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。 
            Object property = field.get(owner); 
            return property; 
        } 
         
        /** 
         * 获得某个类的静态属性 
         * @param className 
         * @param fieldName 
         * @return 
         * @throws Exception 
         * 2013-4-11 上午11:35:10 
         * @author zhao_xingcai 
         */ 
        @SuppressWarnings("unchecked") 
        public Object getStaticProperty(String className, String fieldName) 
                throws Exception { 
            //首先得到这个类的Class 
            Class ownerClass = Class.forName(className); 
            //通过Class得到类声明的属性 
            Field field = ownerClass.getField(fieldName); 
            //静态属性,直接从类的Class里取 
            Object property = field.get(ownerClass); 
            return property; 
        } 
         
        /** 
         * 获取某个对象的方法 
         * @param owner 
         * @param methodName 
         * @param args 
         * @return 
         * @throws Exception 
         * 2013-4-11 上午11:39:05 
         * @author zhao_xingcai 
         */ 
        @SuppressWarnings("unchecked") 
        public Object invokeMethod(Object owner, String methodName, Object[] args) 
                throws Exception { 
            //或得这个类的Class 
            Class ownerClass = owner.getClass(); 
            //配置参数的Class数组,作为寻找Method的条件 
            Class[] argsClass = new Class[args.length]; 
            for (int i = 0, j = args.length; i < j; i++) { 
                argsClass[i] = args[i].getClass(); 
            } 
            //通过Method名和参数的Class数组得到要执行的Method 
            Method method = ownerClass.getMethod(methodName, argsClass); 
            //执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值 
            return method.invoke(owner, args); 
        } 
         
        /** 
         * 执行某个类的静态方法 
         * @param className 
         * @param methodName 
         * @param args 
         * @return 
         * @throws Exception 
         * 2013-4-11 上午11:40:31 
         * @author zhao_xingcai 
         */ 
        @SuppressWarnings("unchecked") 
        public Object invokeStaticMethod(String className, String methodName, 
                Object[] args) throws Exception { 
            //获取该类的class 
            Class ownerClass = Class.forName(className); 
            Class[] argsClass = new Class[args.length]; 
                for (int i = 0, j = args.length; i < j; i++) { 
            } 
            Method method = ownerClass.getMethod(methodName, argsClass); 
            //invoke的一个参数是null,因为这是静态方法,不需要借助实例运行 
            return method.invoke(null, args); 
        } 
         
        /** 
         * 新建实例,执行带参数的构造函数来新建实例的方法。 
         * 如果不需要参数,可以直接使用newoneClass.newInstance()来实现。 
         * @param className 
         * @param args 
         * @return 
         * @throws Exception 
         * 2013-4-11 上午11:41:27 
         * @author zhao_xingcai 
         */ 
        @SuppressWarnings("unchecked") 
        public Object newInstance(String className, Object[] args) throws Exception { 
            //得到要构造的实例的Class 
            Class newoneClass = Class.forName(className); 
            //得到参数的Class数组 
            Class[] argsClass = new Class[args.length]; 
                for (int i = 0, j = args.length; i < j; i++) { 
            } 
            //得到构造函数  
            Constructor cons = newoneClass.getConstructor(argsClass); 
            //新建实例 
            return cons.newInstance(args); 
        } 
         
        /** 
         * 判断是否为某个类的实例 
         * @param obj 
         * @param cls 
         * @return 
         * 2013-4-11 上午11:42:59 
         * @author zhao_xingcai 
         */ 
         @SuppressWarnings("unchecked") 
        public boolean isInstance(Object obj, Class cls) { 
            return cls.isInstance(obj); 
        } 
          
         /** 
          * 得到数组中的某个元素 
          * @param array 
          * @param index 
          * @return 
          * 2013-4-11 上午11:43:33 
          * @author zhao_xingcai 
          */ 
         public Object getByArray(Object array, int index) { 
            return Array.get(array, index); 
        } 

    package baseJava;

    import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    public class Reflect {

     /**
      * @param args
      *            2013-4-11 上午11:20:59
      * @author zhao_xingcai
      */
     public static void main(String[] args) {
      // TODO Auto-generated method stub
      

     }
     
     /**
      * 得到某个对象的属性
      * @param owner
      * @param fieldName
      * @return
      * @throws Exception
      * 2013-4-11 上午11:25:48
      * @author zhao_xingcai
      */
     @SuppressWarnings("unchecked")
     public Object getProperty(Object owner, String fieldName) throws Exception {
      //得到该对象的Class
      Class ownerClass = owner.getClass();
      //通过Class得到类声明的属性
      Field field = ownerClass.getField(fieldName);
      //通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。
      Object property = field.get(owner);
         return property;
     }
     
     /**
      * 获得某个类的静态属性
      * @param className
      * @param fieldName
      * @return
      * @throws Exception
      * 2013-4-11 上午11:35:10
      * @author zhao_xingcai
      */
     @SuppressWarnings("unchecked")
     public Object getStaticProperty(String className, String fieldName)
       throws Exception {
      //首先得到这个类的Class
      Class ownerClass = Class.forName(className);
      //通过Class得到类声明的属性
      Field field = ownerClass.getField(fieldName);
      //静态属性,直接从类的Class里取
      Object property = field.get(ownerClass);
      return property;
     }
     
     /**
      * 获取某个对象的方法
      * @param owner
      * @param methodName
      * @param args
      * @return
      * @throws Exception
      * 2013-4-11 上午11:39:05
      * @author zhao_xingcai
      */
     @SuppressWarnings("unchecked")
     public Object invokeMethod(Object owner, String methodName, Object[] args)
       throws Exception {
      //或得这个类的Class
      Class ownerClass = owner.getClass();
      //配置参数的Class数组,作为寻找Method的条件
      Class[] argsClass = new Class[args.length];
      for (int i = 0, j = args.length; i < j; i++) {
       argsClass[i] = args[i].getClass();
      }
      //通过Method名和参数的Class数组得到要执行的Method
      Method method = ownerClass.getMethod(methodName, argsClass);
      //执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值
      return method.invoke(owner, args);
     }
     
     /**
      * 执行某个类的静态方法
      * @param className
      * @param methodName
      * @param args
      * @return
      * @throws Exception
      * 2013-4-11 上午11:40:31
      * @author zhao_xingcai
      */
     @SuppressWarnings("unchecked")
     public Object invokeStaticMethod(String className, String methodName,
       Object[] args) throws Exception {
      //获取该类的class
      Class ownerClass = Class.forName(className);
      Class[] argsClass = new Class[args.length];
       for (int i = 0, j = args.length; i < j; i++) {
      }
      Method method = ownerClass.getMethod(methodName, argsClass);
      //invoke的一个参数是null,因为这是静态方法,不需要借助实例运行
      return method.invoke(null, args);
     }
     
     /**
      * 新建实例,执行带参数的构造函数来新建实例的方法。
      * 如果不需要参数,可以直接使用newoneClass.newInstance()来实现。
      * @param className
      * @param args
      * @return
      * @throws Exception
      * 2013-4-11 上午11:41:27
      * @author zhao_xingcai
      */
     @SuppressWarnings("unchecked")
     public Object newInstance(String className, Object[] args) throws Exception {
      //得到要构造的实例的Class
      Class newoneClass = Class.forName(className);
      //得到参数的Class数组
      Class[] argsClass = new Class[args.length];
       for (int i = 0, j = args.length; i < j; i++) {
      }
      //得到构造函数
      Constructor cons = newoneClass.getConstructor(argsClass);
      //新建实例
      return cons.newInstance(args);
     }
     
     /**
      * 判断是否为某个类的实例
      * @param obj
      * @param cls
      * @return
      * 2013-4-11 上午11:42:59
      * @author zhao_xingcai
      */
      @SuppressWarnings("unchecked")
     public boolean isInstance(Object obj, Class cls) {
      return cls.isInstance(obj);
     }
     
      /**
       * 得到数组中的某个元素
       * @param array
       * @param index
       * @return
       * 2013-4-11 上午11:43:33
       * @author zhao_xingcai
       */
      public Object getByArray(Object array, int index) {
      return Array.get(array, index);
     }
    }

  • 相关阅读:
    jquery $.post specification
    鸟语2010.5.5
    不使用ubuntu代理
    how to check network's stablity?
    python float decimal issue
    how to check network's stablity?
    session的作用是什么?
    bottle json issure
    我强烈建议,不要想念komdo的ctrl+r
    how to count files in directory
  • 原文地址:https://www.cnblogs.com/yunxiblog/p/5186369.html
Copyright © 2020-2023  润新知