




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、精選文檔12.1 Java類加載機(jī)制前面我們給大家介紹過JVM的功能(供應(yīng)運行時環(huán)境、垃圾回收機(jī)制和供應(yīng)中立的體系結(jié)構(gòu))。在供應(yīng)運行時環(huán)境中有個子功能是ClassLoader(類加載器),它主要用于將主類(即包含了main方法的類)加載到JVM的code segment(代碼區(qū))。然后運行環(huán)境找到main方法(程序入口)開頭執(zhí)行程序。在整個程序運行的過程中,會有更多的class被動態(tài)Load到內(nèi)存中。類加載機(jī)制如圖12-1所示:圖12-1 類加載機(jī)制需要留意的是:類并非一次性就全部加載完畢,而是在需要的時候(運行期間)動態(tài)加載到內(nèi)存。利用java -verbose:class Test可以觀看
2、類的具體加載過程。12.2 Java反射機(jī)制什么是反射Java 程序在運行期間可以動態(tài)加載、解析和使用一些在編譯階段并不確定的類型數(shù)據(jù),這一機(jī)制被稱為反射(Reflection)。反射庫(reflection library)供應(yīng)了一個格外豐富且細(xì)心設(shè)計的工具類,以便編寫能夠動態(tài)操縱Java代碼的程序。使用反射,在設(shè)計和運行中添加新類時,能夠快速的應(yīng)用開發(fā)工具動態(tài)的查詢新添加類的力量。反射方式反射機(jī)制供應(yīng)的功能·加載運行時才能確定的數(shù)據(jù)類型·解析類的結(jié)構(gòu)、分析類的力量、獵取其內(nèi)部信息·操作類(進(jìn)行實例化訪問非靜態(tài)成員,直接利用類名訪問靜態(tài)成員)或其實例(訪問屬性、
3、調(diào)用方法、創(chuàng)建新對象)12.2.1 Class類在程序運行期間,Java運行時系統(tǒng)始終為全部的對象維護(hù)一個被稱為運行時的類型標(biāo)識,被稱為Class(留意與class的區(qū)分)。通過 Class可以完整的得到一個類中的完整結(jié)構(gòu),包括此類中的方法定義,屬性定義等。Class是反射的源頭或入口,通過查看JDK掛念手冊其常見方法如圖:12.2.2 如何獵取Class類對象 針對引用數(shù)據(jù)類型·通過ClassLoader的loadClass方法Class c1 = ClassLoader.getSystemClassLoader().loadClass("com.itjo
4、b.Person");·調(diào)用靜態(tài)方法Class.forName()Class.forName("com.itjob.Person");Class.forName("oracle.jdbc.dirver.OracleDriver");·調(diào)用Object類中定義的getClass()方法Person p = new Person();Class c1 = p.getClass();Class c2 = "Hello".getClass();·使用.class表達(dá)式Class c1 = String.
5、class;Class c2 = com.itjob.Person.class;Class c3 = oracle.jdbc.dirver.OracleDriver.class; 針對基本數(shù)據(jù)類型及void·使用.class 表達(dá)式Class c1 = int.class;Class c2 = double.class;Class c3 = void.class;·調(diào)用相應(yīng)封裝類的Type 屬性Class c1 = Integer.TYPE;Class c2 = Double.TYPE;Class c3 = Void.TYPE;示例如下:try /1. 引用
6、數(shù)據(jù)類型/1.1 利用ClassLoader類的loaderClass("類全名稱");手動加載,會有特別System.out.println(ClassLoader.getSystemClassLoader().loadClass("com.itjob.Person" ).getName();/1.2 利用Class.forName(類全名稱);手動加載,會有特別System.out.println(Class.forName("com.itjob.Person").getName();/1.3 調(diào)用Object類中定義的getCl
7、ass()方法System.out.println(new Person().getClass().getName();/1.4 使用.class表達(dá)式System.out.println(Person.class.getName();/2. 基本數(shù)據(jù)類型和void/2.1 使用.class表達(dá)式System.out.println(int.class.getName();System.out.println(double.class.getName();System.out.println(void.class.getName();/2.2 通過各自的包裝類.TYPESystem.out.p
8、rintln(Integer.TYPE);System.out.println(Double.TYPE); catch (ClassNotFoundException e) e.printStackTrace();12.2.3 獵取實例對象不光可以取得對象所在類的信息,也可以直接通過Class類的newInstance方法進(jìn)行對象實例化操作。newInstance方法原型如下:public T newInstance() throws InstantiationException,IllegalAccessException調(diào)用過程:p.getClass().newInstance();或:P
9、erson.class.newInstance();或:Class.forName("com.itjob.Person").newInstance()創(chuàng)建一個Person類的實例。newInstance方法調(diào)用默認(rèn)的構(gòu)造器初始化新創(chuàng)建的對象,假如這個類沒有默認(rèn)的構(gòu)造器,就會拋出一個特別。要想調(diào)用有參構(gòu)造方法,則必需使用Constructor類的newInstance方法。12.2.4 獵取類的結(jié)構(gòu)Class類的實例用于表示運行時的Java數(shù)據(jù)類型,包括類、接口、數(shù)組、枚舉、注解、基本數(shù)據(jù)類型。在類加載時,Java虛擬機(jī)會自動創(chuàng)建相應(yīng)Class對象。通過反射得到一個類的完整結(jié)
10、構(gòu)要使用到j(luò)ava.lang.reflect包,此包下的常見類如下:java.lang.reflect.Fieldjava.lang.reflect.Methodjava.lang.reflect.Constructor<T>java.lang.reflect.Modifierjava.lang.reflect.Array 獵取類實現(xiàn)的全部接口要想取得一個類所實現(xiàn)的全部接口,則必需使用 Class類中的getInterfaces()方法。此方法定義如下:public Class getInterfaces()。由于一個類可以同時實現(xiàn)多個接口,因此此方法返回一個Cla
11、ss類的對象數(shù)組,之后就可以直接利用Class類中的getName()方法輸出即可。示例如下:interface Ainterface Bclass Person implements A, Bpublic class Test public static void main(String args) Class c = Person.class.getInterfaces();for(Class cc : c)System.out.println(cc.getName(); 獵取類所繼承的父類一個類可以實現(xiàn)多個接口,但是只能繼承一個父類,假如沒有明確的指明繼承那個類,則確定繼
12、承的是Object類。所以要想取得一個類的父類,可以直接使用Class類中的getSuperclass()方法。此方法定義如下:public Class<? super T> getSuperclass()。此方法返回的是Class實例,和之前得到接口一樣,可以通過getName()方法取得名稱。 示例如下:class Aclass Person extends Apublic class Test public static void main(String args) System.out.println(Person.class.getSuperclass().getName
13、(); 獵取類中的全部構(gòu)造方法可以直接使用Class類中的getConstructors()方法或getDeclaredConstructors()方法取得本類中的全部構(gòu)造方法。這兩個方法的返回類型都是Constructor的數(shù)組。Constructor類定義在java.lang.reflect包中,常用方法如下:取得訪問修飾權(quán)限的時候卻發(fā)覺返回的是一個int數(shù)字而不是 public等類型的修飾符關(guān)鍵字。這是由于在整個Java中對于方法的修飾符是使用一頂?shù)臄?shù)字表示出來的,如圖所示:假如要想把這個數(shù)字還原成用戶可以看懂的關(guān)鍵字,則必需依靠Modifier類完成,此類定義在java
14、.lang.reflect包中。直接使用Modifier類的以下方法即可將修飾符轉(zhuǎn)變:public static String toString(int mod);示例如下:import java.lang.reflect.*;class Personprivate String name;private int age;public Person() public Person(String name, int age) = name;this.age = age;Overridepublic String toString() / TODO Auto-generated
15、 method stubreturn "我叫" + + ",我今年" + this.age;public class Test public static void main(String args) /獵取全部的構(gòu)造方法Constructor<?> cs = Person.class.getDeclaredConstructors();for(Constructor<?> c : cs)/遍歷全部的構(gòu)造方法/輸出構(gòu)造方法的修飾符System.out.println("構(gòu)造器修飾符:" +
16、Modifier.toString(c.getModifiers();/輸出構(gòu)造方法名稱System.out.println("構(gòu)造方法名:" + c.getName();/輸出構(gòu)造方法全部參數(shù)Class<?> ct = c.getParameterTypes();if(ct.length = 0)System.out.println("這是無參的構(gòu)造方法");elseint i = 0;for(Class<?> p : ct)System.out.println("參數(shù)" + (i+1) + ":&
17、quot; + p.getName();i+;現(xiàn)在我們已經(jīng)知道如何獵取一個類的全部構(gòu)造方法規(guī)范,此時我們可以利用Constructor類的newInstance調(diào)用有參的構(gòu)造方法來實例化對象,其過程如下:1、通過Class類中的getConstructors()方法或getDeclaredConstructors()取得本類中的全部構(gòu)造方法。2、分析每個構(gòu)造方法的參數(shù)狀況,了解每個構(gòu)造方法的原型。3、通過Class類中的getDeclaredConstructor(Class<?>. parameterTypes)方法,向構(gòu)造方法中傳遞一個對象數(shù)組進(jìn)去,里面包含了構(gòu)造方法中所需的各
18、個參數(shù)。4、通過調(diào)用Constructor的newInstance(Object. initargs)方法實例化對象。示例如下:try Constructor<?> c = Person.class.getDeclaredConstructor(String.class, int.class);System.out.println(c.newInstance("張三", 25); catch (IllegalArgumentException e) e.printStackTrace(); catch (InstantiationException e) e.p
19、rintStackTrace(); catch (IllegalAccessException e) e.printStackTrace(); catch (InvocationTargetException e) e.printStackTrace();catch (SecurityException e1) e1.printStackTrace(); catch (NoSuchMethodException e1) e1.printStackTrace(); 獵取類中的方法要想取得一個類中的全部方法,可以使用Class類中的getDeclaredMethods()方法,此方
20、法返回一個Method類的對象數(shù)組,假如要想進(jìn)一步取得方法的具體信息,例如:方法的參數(shù),拋出的特別聲明等等內(nèi)容,就必需依靠Method類來完成。輸出本類中的全部方法:public Method getDeclaredMethods() throws SecurityException輸出全部的方法(包括父類中的):public Method getMethods() throws SecurityException方法操作:取得全部的返回值:public Class<?> getReturnType()取得全部的參數(shù):public Class<?> getParamet
21、erType()取得修飾符:public int getModifiers()取得特別信息:public Class<?> getExceptionType()示例如下:/ 獲得非繼承的全部方法Method methods = Person.class.getDeclaredMethods();for (Method m : methods) System.out.print(Modifier.toString(m.getModifiers() + " "+ m.getReturnType().getName() + " " + m.getN
22、ame() + "(");Class<?> paras = m.getParameterTypes();for (Class<?> p : paras) System.out.print(p.getName() + " ");System.out.println(")");通過Class類的getMethod方法或getDeclaredMethod方法,依據(jù)一個類中的方法名稱及參數(shù)類型取得Method對象,并通過invoke()方法調(diào)用指定的方法。invoke方法原型如下:public Object invok
23、e(Object obj, Object. args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException·假如要調(diào)用的方法是類的靜態(tài)方法,obj指定為null即可,然后后面是參數(shù)列表。·假如是非靜態(tài)方法,必需傳入一個類的實例化對象,然后后面是參數(shù)列表。假如方法是無參方法:m.invoke(obj); /非靜態(tài)m.invoke(null);/靜態(tài)假如方法帶參數(shù):m.invoke(obj, 10, 20);/靜態(tài)m.invoke(null, 10, 20);/非靜
24、態(tài)示例如下:Person類中的方法原型:public void fun1(int a, int b);public static void fun2(int a, String b);調(diào)用方式:/ 非靜態(tài)方法調(diào)用方式method = Person.class.getDeclaredMethod("fun1", int.class, int.class);method.invoke(obj, 10, 20);/ 靜態(tài)方法調(diào)用方式smethod = Person.class.getDeclaredMethod("fun2", int.class, Strin
25、g.class);smethod.invoke(null, 10, "hello world java"); 獵取類中的屬性在反射操作中也同樣可以取得一個類中的全部屬性,但是在取得屬性的時候有以下兩種不同的操作:得到本類、實現(xiàn)的接口和父類中的全部公共屬性:public Field getFields() throws SecurityException得到本類中的全部屬性(包括私有屬性):public Field getDeclaredFields() throws SecurityException以上方法返回的都是Field的數(shù)組,每一個Field對象就
26、表示類中的一個屬性。屬性操作:取得屬性修飾符:public int getModifiers()取得屬性類型:public Class<?> getType()取得屬性名稱:public String getName()示例如下:/ 獵取類中全部的屬性Field field = Person.class.getDeclaredFields();for(Field f : field)/ 屬性修飾符System.out.print(Modifier.toString(f.getModifiers() + " ");/ 屬性類型System.out.print(f.
27、getType().getName() + " ");/ 屬性名稱System.out.println(f.getName();setter()及getter()方法是一個標(biāo)準(zhǔn)的屬性的訪問方法,假如一個類的屬性被封裝,則必需通過setter及getter方法設(shè)置和取得屬性的值。實際上此方法的操作之所以要這樣規(guī)定,主要緣由是由于反射機(jī)制可以賜予支持的。通過反射可以調(diào)用setter()及getter()方法。假如要操作一個類中的屬性,則可以通過Field類來完成。而不必麻煩的通過setter()及getter()得到。取得公共屬性:public Field getField(S
28、tring name) throws NoSuchFieldException, SecurityException取得本類屬性(包括私有):public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException取得屬性內(nèi)容:public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException設(shè)置屬性內(nèi)容:public void set(Object obj, Object value)
29、throws IllegalArgumentException, IllegalAccessException設(shè)置屬性可見(在訪問私有屬性的時候,必需讓這個屬性可見):public void setAccessible(boolean flag) throws SecurityException示例如下:Field f = Person.class.getDeclaredField("name");/name是本類中的私有屬性f.setAccessible(true);/設(shè)置其可見f.set(obj, "李四");/設(shè)置屬性System.out.prin
30、tln(f.get(obj);/取得屬性與方法類似,假如類中的屬性是static修飾的,則get和set方法中的obj為null即可。獵取類結(jié)構(gòu)信息綜合實例:package reflect;import java.lang.reflect.*;import java.util.Scanner;public class ReflectTest public static void printConstructors(Class<?> cl)Constructor<?> constructors = cl.getDeclaredConstructors();for(Cons
31、tructor<?> c : constructors)String name = c.getName();System.out.print(" ");String modifiers = Modifier.toString(c.getModifiers();if(modifiers.length() > 0)System.out.print(modifiers + " ");System.out.print(name + "(");Class<?> paramTypes = c.getParameter
32、Types();for(int i = 0; i < paramTypes.length; i+)if(i > 0)System.out.print(", ");System.out.print(paramTypesi.getName();System.out.println(");");public static void printMethods(Class<?> cl)Method methods = cl.getDeclaredMethods();for(Method m : methods)String name = m
33、.getName();Class<?> retType = m.getReturnType();System.out.print(" ");String modifiers = Modifier.toString(m.getModifiers();if(modifiers.length() > 0)System.out.print(modifiers + " ");System.out.print(retType.getName() + " " + name + "(");Class<?&g
34、t; paramTypes = m.getParameterTypes();for(int i = 0; i < paramTypes.length; i+)if(i > 0)System.out.print(", ");System.out.print(paramTypesi.getName();System.out.println(");");public static void printFields(Class<?> cl)Field fields = cl.getDeclaredFields();for(Field f
35、: fields)Class<?> type = f.getType();String name = f.getName();System.out.print(" ");String modifiers = Modifier.toString(f.getModifiers();if(modifiers.length() > 0)System.out.print(modifiers + " ");System.out.println(type.getName() + " " + name + "")
36、;public static void main(String args) String name = null;if(args.length > 0)name = args0;elseScanner in = new Scanner(System.in);System.out.print("Enter class name(eg:java.util.Date):");name = in.next();try Class<?> cl = Class.forName(name);Class<?> supercl = cl.getSuperclas
37、s();String modifiers = Modifier.toString(cl.getModifiers();if(modifiers.length() > 0)System.out.print(modifiers + " ");System.out.print("class " + name);if(supercl != null && supercl != Object.class)System.out.print(" extends " + supercl.getName();System.out.
38、print("nn");printConstructors(cl);System.out.println();printMethods(cl);System.out.println();printFields(cl);System.out.println(""); catch (ClassNotFoundException e) / TODO Auto-generated catch blocke.printStackTrace();12.2.5 通過反射操作數(shù)組反射機(jī)制不光只能用在類中,也可以應(yīng)用在任意的引用數(shù)據(jù)類型上。當(dāng)然,這就包含了數(shù)組,數(shù)組使用
39、Array類完成。Class類中存在以下一個方法,用于返回一個數(shù)組對象的實例:public Class<?> getComponentType ()接下來可以利用java.lang.reflect包中的Array類的有些方法來操作:開拓新數(shù)組:public static Object newInstance(Class<?> componentType, int. dimensions) throws IllegalArgumentException, NegativeArraySizeException得到數(shù)組指定下標(biāo)的內(nèi)容:public static Object
40、get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException修改內(nèi)容:public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException示例如下:int arr = 1, 3, 5, 7, 9;Class<?> c = arr.getClass().getComponentTyp
41、e();/ 創(chuàng)建新數(shù)組對象,長度為10Object newArr = Array.newInstance(c, 10);/ 利用set修改指定下標(biāo)的值A(chǔ)rray.set(newArr, 0, 10);Array.set(newArr, 1, 20);/ 利用get返回指定下標(biāo)的值System.out.println("數(shù)組下標(biāo)為1的元素為:" + Array.get(newArr, 1);12.2.6 反射與Annotation一個Annotation要想讓其變得有意義,則必需結(jié)合放射機(jī)制取得Annotation中設(shè)置的全部內(nèi)容。在 Class類中存在以下幾種與Annota
42、tion 操作有關(guān)的方法:實際應(yīng)用ORM(實體關(guān)系映射orm 即Object-relational mapping)示例如下:package com.itjob;import java.lang.annotation.*;import java.lang.reflect.Field;/ 數(shù)據(jù)庫中的類型列表enum dbType varchar,number/ 該注解指明字段的名稱和對應(yīng)的數(shù)據(jù)類型Target(value=ElementType.FIELD)Retention(value=RetentionPolicy.RUNTIME)interface ColumnAnnotation pub
43、lic String columnName();/ 數(shù)據(jù)庫中字段的名稱public dbType dbtype();/ 數(shù)據(jù)庫中字段的類型/ 該注解指明數(shù)據(jù)庫中表的名稱Target(value=ElementType.TYPE)Retention(value=RetentionPolicy.RUNTIME)interface TableAnnotation public String tableName();/數(shù)據(jù)庫中表的名稱TableAnnotation(tableName="student")/ 表名稱為studentclass Student / 對應(yīng)表student
44、中字段名sname,類型varcharColumnAnnotation(columnName="sname", dbtype=dbType.varchar)private String name;/ 對應(yīng)表student中字段名sage,類型numberColumnAnnotation(columnName="sage", dbtype=dbType.number)private int age;public Student(String name, int age) = name;this.age = age;public Stri
45、ng getName() return name;public void setName(String name) = name;public int getAge() return age;public void setAge(int age) this.age = age;class ORMHelp/ 把對象轉(zhuǎn)換為相應(yīng)的sql語句插入到數(shù)據(jù)庫中public void insert(Object table)StringBuilder sb = new StringBuilder();sb.append("insert into ");/ 獲得對象的Class實例Cla
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 安徽省安慶一中江西省南昌二中等五省六校(K12聯(lián)盟)高三上學(xué)期期末聯(lián)考英語試題
- 福建省莆田市第二十四中學(xué)2017-2018學(xué)年高一上學(xué)期期末考?xì)v史試題
- 工會組織在企業(yè)文化建設(shè)中的獨特作用
- 九年義務(wù)教育全日制初級中學(xué)英語教學(xué)大綱( 試用修訂版)
- 初中物理教學(xué)中小組合作學(xué)習(xí)模式的運用
- 益氣健脾和血祛痰法對冠心病穩(wěn)定型心絞痛患者神經(jīng)遞質(zhì)的影響
- 牙鲆抗遲緩愛德華氏菌病F4代家系建立及世代抗病力的分析
- 新課標(biāo)2024-2025學(xué)年高中英語課時分層作業(yè)14SectionⅡ含解析新人教版必修2
- 2025版高考?xì)v史二輪復(fù)習(xí)專題限時集訓(xùn)3仁義立國的儒學(xué)思想和傳統(tǒng)文化
- 空調(diào)維修施工方案
- AQ-T 3002-2021阻隔防爆橇裝式加油(氣)裝置技術(shù)要求
- (正式版)QBT 8022-2024 冷凍飲品 食用冰
- 神經(jīng)經(jīng)濟(jì)學(xué)展示
- 危大工程安全檢查錄表
- 北師大版心理健康四年級下冊全冊教案教學(xué)設(shè)計
- 品牌服裝設(shè)計課件
- 肝病科進(jìn)修總結(jié)匯報
- 化妝品企業(yè)質(zhì)量管理手冊
- 區(qū)域間的數(shù)據(jù)共享協(xié)議
- 建筑工程施工日志模板
- NB-T 47013.7-2012(JB-T 4730.7) 4730.7 承壓設(shè)備無損檢測 第7部分:目視檢測
評論
0/150
提交評論