轉:http://blog.csdn.net/xingcaizxc/article/details/8786744
平時看代碼時,總是碰到這些即熟悉又陌生的名次,每天都與他們相見,但見面後又似曾沒有任何的交集,所以今天我就來認識下這兩個江湖俠客的背景:
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();
- 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反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。
- 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);
- }
- }
-