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

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);
 }
}

JavaReflection(转载)的更多相关文章

  1. Crystal Clear Applied: The Seven Properties of Running an Agile Project (转载)

    作者Alistair Cockburn, Crystal Clear的7个成功要素,写得挺好. 敏捷方法的关注点,大家可以参考,太激动所以转载了. 原文:http://www.informit.com ...

  2. RTP与RTCP协议介绍(转载)

    RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.RTP中没有连接的概念,本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完 ...

  3. 《Walking the callstack(转载)》

    本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...

  4. [转载]MVVM模式原理分析及实践

    没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...

  5. [转载]:STM32为什么必须先配置时钟再配置GPIO

    转载来源 :http://blog.csdn.net/fushiqianxun/article/details/7926442 [原创]:我来添两句,就是很多同学(包括我)之前搞低端单片机,到了stm ...

  6. [转载]从MyEclipse到IntelliJ IDEA-让你摆脱鼠标,全键盘操作

    从MyEclipse转战到IntelliJ IDEA的经历 注转载址:http://blog.csdn.net/luoweifu/article/details/13985835 我一个朋友写了一篇“ ...

  7. TCP同步与异步,长连接与短连接【转载】

    原文地址:TCP同步与异步,长连接与短连接作者:1984346023 [转载说明:http://zjj1211.blog.51cto.com/1812544/373896   这是今天看到的一篇讲到T ...

  8. 在CentOS 7/6.5/6.4 中安装Java JDK 8(转载)

    转载在CentOS 7/6.5/6.4 中安装Java JDK 8 首先,在你的服务器上运行一下更新. yum update 然后,在您的系统上搜索,任何版本的已安装的JDK组件. rpm -qa | ...

  9. 用C#实现MD5的加密(转载)

    方法一 首先,先简单介绍一下MD5 MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer scien ...

随机推荐

  1. $cordovaNetwork 使用

    1 .安装插件 直接安装: cordova plugin add cordova-plugin-network-information 下载到本地安装: https://github.com/apac ...

  2. 19-10-26-F

    ZJ一下: T1码了暴力但是并没有开出来身高的神奇性质…… T2打模拟,但是只摸了卅分 T3不会,码了一个测试点分治.10分 TJ一下: T1. 发现身高范围在$[140,200]$时,直接去重跑$\ ...

  3. 88 Lowest Common Ancestor of a Binary Tree

    原题网址:https://www.lintcode.com/problem/lowest-common-ancestor-of-a-binary-tree/description 描述 给定一棵二叉树 ...

  4. 为什么@RestController返回的Date类型是Long型

    最近项目中发现一个好玩的事情:本地调试时,返回的date是日期格式yyyy-MM-dd HH:mm:ss,但发布到服务器后就变为Long型的时间戳了 最后查到的原因很简单,因为发布服务器启动时的脚本加 ...

  5. jeecms v9导入myeclipse 2015 ehcache.xml报错问题

    1.找不到ehcache.xml文件问题 cache-context.xml <property name="configLocation"> <value> ...

  6. 【DM8168学习笔记6】学习思路整理

        DavinciDM8168的开发是一套大的系统,包括ARM.DSP.以及他们的通信协作.对学习思路做简单总结:     一.  对于整体框架的把握 参考了一些文章.介绍davinci整体基础知 ...

  7. Python爬虫笔记【一】模拟用户访问之webdriver用户登入——第三次(8)

    经过post方法之后,因为有动态的value值所以再此回到用webdriver的解决上,但是在下载图片上会打开新打开一个链接,导致与网页图片不同即验证码同步问题,没办法只能想了一个笨法子,网页截图,唉 ...

  8. python 为 class 添加新的属性和方法

    通过继承: >>> class Point(namedtuple('Point', ['x', 'y'])): ... __slots__ = () ... @property .. ...

  9. CImage 是基于GDI+的,很老的一篇文章,我很久很久以前看到过的

    在许多资料上都说CImage类是基于GDI+的,但是为什么是基于GDI+的呢? 因为使用这个类时,并没有加入#include <gdiplus.h> ,也没有在程序开始和结束时分别写GDI ...

  10. Luogu P1967 货车运输(Kruskal重构树)

    P1967 货车运输 题面 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 \ ...