国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

反射相關

2019-11-09 13:52:04
字體:
來源:轉載
供稿:網友

反射相關:[利用反射的各種操作都是在運行期進行的. ]

1.在面向對象的世界里,萬事萬物皆對象.

但是java語言中,靜態的成員 與基本數據類型類 不是對象.

類是不是對象? 誰的對象呢?

類是對象,任何類都是java.lang.Class類的實例對象.

2.類java.lang.Class的對象到底如何表示呢?(與普通類的對象區別)

[There is a class named 'Class'] 一個名叫Class的類.

//官方稱呼為: (一個類的)類類型(Class Type).

//一個類只能有一個類類型,或者理解成,它只是Class類的一個具體的實例對象.

所以,不管通過以下三種中任何一種方式,得到同一個類的類類型都是相同的.(都是同一個Class類的實例對象).

[上面關于類類型的理解一定要把握好.] 

已知一個類Foo, Foo f1=new Foo();

1.Class c1=Foo.class;[實際在告訴我們任何一個類都有一個隱含的靜態成員變量class]

2.Class c2=f.getClass();[通過某個類的一個對象獲取此類的類類型]

3.Class c3=Class.forName("包名.類名");[直接指定類的全稱進行獲取]

并且,c1==c2==c3.因為都是指Class的同一個實例對象Foo.該類稱為Foo的類類型.

得到了某個類的類類型后,我們就可以通過它去創建該類的實例對象:

Foo f2 = (Foo) c1.newInstance();[前提是此類(Foo)必須要有無參構造方法]

3.Java動態加載類

1.Class.forName("類的全稱").第三種途徑則是動態加載類.

.不僅表示了類的類類型,還代表了是動態加載類.

.要區分開編譯與運行.

.編譯時刻加載類是靜態加載類/運行時刻加載類是動態加載類.

public Class Office{

public static void main(String[] args){

//使用NEW關鍵字創建對象,是靜態加載類,在編譯時刻就需要

//加載所有的可能用到的類.所以相關的類不論是否用到都必須存在.

if("Word".equals(args[0]){

Word  w=new Word();

w.start();

}

if("Excel".equals(args[0]){

Excel e=new Excel();

e.start();

}

}

}

但是,我們更希望在使用的時候,用到哪個類(功能)去加載哪個類,不用的不加載.那么上面的例子是做不到的.因為不論用到哪個,其他的類必須全部存在.

那么,如何解決?----動態加載類,在運行時,用到哪個類再去加載哪個類.

public Class OfficeBetter{

public static void main(String [] args){

//動態加載指定類.

Class c=Class.forName(args[0]);

OfficeAble oa=(OfficeAble)c.newInstance();

//多態:實際是哪個類,就調用實際類中此項功能.

oa.start();

}

}

//給各個類制定一個統一的標準.(多態的應用)

public interface OfficeAble{

void start();

}

這樣在編譯OfficeBetter時,是完全通過的.而在運行時,需要你去指定具體用到哪個類,它就會去加載這個類.(非常好的設計思想@_@)

[所以,以后功能性的類盡量用這種設計思想,盡量用動態加載.這樣更新的時候,只需要添加,刪除各個功能類并且讓各個功能類實現這一統一的標準(接口)]

4.反射獲取方法的信息(返回值類型,方法名,參數類型)

Class c1=int.class;

Class c2=String.class;

Class c3=double.class;//與下面的Double完全不同.

Class c4=Double.class;

Class c5=void.class;

基本數據類型,void都有對應的類類型.

public Class ClassUtil{

public static void PRintMethodInfo(Object obj){

//首先獲取對象所屬類的類類型

Class c=obj.getClass();

//獲取類的類名稱

system.out.println("類的名稱:"+c.getName());

//java.lang.reflect.Method類,萬事萬物皆對象,那么任何一條方法也是這//Method類的對象.

//此方法獲取的是所有的public 的函數,包括從父類繼承來的方法(肯定是public方法)

Method[] methods=c.getMethods();

//此方法返回的是此類自己聲明的所有方法(包括public&private方法)

Method[] methods1=c.getDeclaredMethods();

for(int i=0;i<methods.length;i++){

//得到返回值類型的類類型(int.class,void.class)

Class returnType=methods[i].getReturnType();

//得到了返回值類型的名字.

system.out.print(returnType.getName());

//得到了方法的名字.

system.out.print(methods[i].getName());

//得到方法的參數類的類類型

Class[] paramTypes=method[i].getParameterTypes();

for(int j=0;j<paramTypes.length;j++){

//得到具體某個參數類型的名字

system.out.print(paramTypes[j].getName());

}

}

}

//成員變量也是對象.

//java.lang.reflect.Field類的對象.

//此類封裝了關于成員變量的操作.

//getFields():獲取所有public的成員變量

//getDeclaredFields():獲取所有此類自己聲明的成員變量(public&private)

public static void printFieldInfo(Object obj){

Class c=obj.getClass();

Field[] fields=c.getDeclaredFields();

for(Field field:fields){

//獲得此成員變量的類類型

Class fieldType=field.getType();

String typeName=fieldType.getName();

//得到成員變量的名字.

String fieldName=field.getName();

system.out.println("fieldType:"+typeName+","+"fieldName:"+fieldName);

}

}

public static void printConstructorInfo(Object object) {//1.由某個類的對象,得到 該類的 類類型.Class<?> cls=object.getClass();//2.由該類的類類型,得到該類的所有指定的構造函數.Constructor[] constructors=cls.getDeclaredConstructors();for (Constructor constructor : constructors) {System.out.print("構造器名稱: "+constructor.getName()+"  :參數類型:");Class[] paramTypes=constructor.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+";");}System.out.println();}}

}

5.方法反射來調用方法.

語法:m.invoke(obj,參數);

obj.print(參數);

//b.print(10,20);方法的反射操作是用method為進行方法調用.與b.print(10,20)效//果一樣.可變參數Object...可以寫成new Object[]{10,20},也可以直接寫入各個參//數:10,20;

public class Test4 {	/**	 * 學習如何獲得方法對象,通過方法對象調用方法執行.	 * @param args	 */	public static void main(String[] args) {		B b=new B();		Class<?> cls=b.getClass();		try {			Method method=cls.getDeclaredMethod("print", new Class[]{int.class,int.class});			Object object=method.invoke(b, 10,20);			Method method2=cls.getDeclaredMethod("print", new Class[]{String.class,String.class});			Object object2=method2.invoke(b, new String[]{"Manny","HaiXia"});			/**			 * 學習如何獲得字段對象,并且更改它的值;			 */			Field field=cls.getDeclaredField("count");			field.setaccessible(true);			field.set(b, 100);			System.out.println(field.get(b));		} catch (NoSuchMethodException | SecurityException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalAccessException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalArgumentException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (InvocationTargetException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (NoSuchFieldException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}			}}class B{	private int count;	public void printCount() {		System.out.println(count);	}	public void print(int a,int b) {		System.out.println(a+b);	}		public void print(String a,String b) {		System.out.println(a.toUpperCase()+","+b.toLowerCase());	}}6.通過反射了解集合泛型 的本質;

/**	 * 集合泛型 的本質是編譯期起檢查作用的.而反射是在運行期進行的,自然就繞過了編譯期的檢查.	 * @param args	 */		public static void main(String[] args) {		ArrayList<String> list1=new ArrayList<>();		ArrayList list2=new ArrayList();		list2.add("hello");		list1.add("hello");		list2.add(20);		Class cls1=list1.getClass();		Class cls2=list2.getClass();		//運行期時,list1&list2的類的類型沒有區別;即不存在了泛型這個檢查;		System.out.println(cls1==cls2);				try {			Method method=cls1.getDeclaredMethod("add",Object.class);			method.invoke(list1	, 20);			System.out.println(list1.size());			//取出時仍然要用反射,繞過編譯期的泛型檢查.			//所以泛型不僅要檢查放的數據類型是否符合泛型,還要檢查拿出的數據類型是否符合泛型;			Method method2=cls1.getDeclaredMethod("get", int.class);			System.out.println(method2.invoke(list1, 1));			/*for(int i=0;i<list1.size();i++){				System.out.println(list1.get(i));			}*/			/*Method[] eMethods=cls1.getDeclaredMethods();			for (Method method : eMethods) {				System.out.print(method.getName()+";");				Class[] paraTypes = method.getParameterTypes();				for (Class class1 : paraTypes) {					System.out.print(class1.getName());									}				System.out.println();			}*/			 		} catch (SecurityException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalArgumentException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (NoSuchMethodException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalAccessException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (InvocationTargetException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}			}


上一篇:百度地圖 定位

下一篇:微信支付集成

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 萍乡市| 临江市| 绥宁县| 外汇| 庆云县| 龙陵县| 大渡口区| 怀集县| 那曲县| 潼关县| 华池县| 中方县| 平凉市| 盐源县| 化州市| 蒙城县| 沈阳市| 同德县| 东海县| 宁陕县| 抚顺市| 封丘县| 旬邑县| 庆阳市| 平度市| 绥江县| 寿阳县| 夏邑县| 秀山| 阜新| 威宁| 磐安县| 平江县| 定日县| 云阳县| 林州市| 临漳县| 荔波县| 芮城县| 广饶县| 清丰县|