天天看點

黑馬程式員——反射、類加載器

                                    ------- android教育訓練、java教育訓練、期待與您交流! ----------

屬性的反射------Field

Student student = new Student("zs",1);
Field name = student.class.getField("name"); //不能擷取private的,這裡擷取的隻是類的屬性,并不是具體某個對象的值。
Field age = student.class.getDeclaredField("age");//可以擷取private的
name.setAccessible(true);暴力發射,強制去取某個對象的具體屬性值。
name.getField(student);//具體擷取student對象的name屬性。

Constructor ms = Class.forName("StringDemo.Student").getDeclaredConstructor();
		
ms.setAccessible(true);
Student s = (Student) ms.newInstance(null);

Student ss = new Student("zs",21);
Field f = ss.getClass().getDeclaredField("name");//擷取private的屬性,這裡隻是擷取類成員,并不是具體對象值。
f.setAccessible(true);//暴力反射
System.out.println(f.get(ss));//這裡才是真正的擷取具體對象的name值。

Field f1 = ss.getClass().getDeclaredField("age");
AccessibleObject[] array = new AccessibleObject[]{f1};//封裝一個AccessibleObject數組,在下面調用靜态發方法,一次對多個對象暴力反射

AccessibleObject.setAccessible(array, true);//對多個對象暴力反射
System.out.println(f1.get(ss));

Method-------------成員方法反射。方法是屬于類的,跟對象沒關系。
Method methods = String.class.getMethod("charAt",int.class);//擷取charAt方法,後面是參數。
System.out.println(methods);
System.out.println(methods.invoke("absdfsf+fdfdf",4));//對應上面擷取的methods方法,因為該方法有2個參數,是以這裡傳遞兩個參數
System.out.println(methods.invoke(null,3));//如果這裡是null那麼說明這個方法是靜态方法,不需要對象。

Method zs = Math.class.getMethod("max", int.class,int.class);
System.out.println(zs.invoke(null, 3,4));

反射main方法-------------
Method  m = TT.class.getMethod("main", String[].class);
m.invoke(null, new Object[]{new String[]{"111"}});
m.invoke(null, (Object)new String[]{"111"});


數組的反射----------------
if(arr1.getClass().isArray()){
	for(int i =0 ;i<arr1.length;i++){
			System.out.println(arr1[i]);//由于數組是Object的類型的
			System.out.println(arr1[i].getClass().getName());//要擷取每一個數組中每一個元素的類型。
		}
	}

判斷一個對象是是否屬于某個類的執行個體
1、用instancof關鍵字
2、用反射 obj.getClass.equals(Object.class);                

加載properties檔案。

new Properties().load(new FileInputStream("dfdf.properties"));

類加載器------classLoader~~~~~~~~~3個類加載器   {BootStrap}第一個加載器,jvm虛拟機核心啟動就加載  C++寫的      ExtClassLoader   AppClassLoader

BootStrap---->第一個加載器,負責JRE/LIB/RT.JRA的加載

ExtCloassLoader---->第二個加載器,負責ext目錄下面的jar檔案加載

AppClassLoader----->第三個加載器,負責CLASSPATH環境變量下面的檔案加載。

Properties properties = new Properties();
InputStream in  = Demo.class.getClassLoader().getResourceAsStream("resources/zs.properties");
p.load(in);
System.out.println(p.get("zs"));


//sun.misc.Launcher$AppClassLoader加載器 加載的
System.out.println(Demo.class.getClassLoader().getClass().getName());


//java.lang.NullPointerException 不代表沒有加載器,他有一個特殊的加載器由C++寫的BootStrap加載的
System.out.println(System.class.getClassLoader().getClass().getName());


//BootStrap---->ExtClassLoader------>AppClassLoader
ClassLoader classLoader = Demo.class.getClassLoader();
for(;classLoader!=null;){
System.out.println(classLoader.getClass().getName());
classLoader = classLoader.getParent();
}                

類加載器的委托機制-----------------------

每個類在被類加載器加載的時候,會先去找上級類加載器去加載。

先是2号加載器發啟加載某個類,2号回去找他的父親1号加載器來加載,如果一号有就加載

如果1号沒有,那麼2号加載器就自己去自己的管轄範圍内找,如果2号加載器也沒有找到

就會抛出異常ClassNotFoundException,并不會給他的孩子3号去找。

自定義類加載器------------

繼承ClassLoader  重寫  findClass方法 傳入一個位元組碼  用提供的方法 解析

轉載于:https://my.oschina.net/u/158350/blog/106795