關於反射的理解-淺談反射

1.反射的基石----->Class類

2,Java程序中的各個Java類屬於同一類事物,描述這類事物的java類名就是Class。

3,Class類代表java類,它的各個實例對象對應各個類在內存中的字節碼。一個類被加載到

內存中,佔有一片存儲空間,這個空間裏面的內容就是類的字節碼不同的類的字節碼是不同的,所以

他們在內存中的內容是不同的。這一個個的空間可分別用一個個的對象來表示,這些對象具有相同的類型(Class類型)。

String s = "abc";
Class clz1 = s.getClass();
Class clz2 = String.class;
Class clz3=null;
try {
clz3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

System.out.println(clz1==clz2);//true
System.out.println(clz1==clz3);//true
System.out.println(clz3==clz2);//true
System.out.println(new Date().getClass() ==clz1);//false同類的字節碼是相同的,不同的類對應的字節碼是不同的。但類型都是Class類。

System.out.println(s instanceof String);//true
System.out.println(clz1 instanceof Class);//true
System.out.println(new Date().getClass() instanceof Class);//true

//判斷是否是基礎類型isPrimitive()
System.out.println(clz1.isPrimitive());//false
System.out.println(int.class.isPrimitive());//true
System.out.println(int[].class.isPrimitive());//false
System.out.println(int[].class.isArray());//true
System.out.println(int.class==Integer.class);//false
System.out.println(int.class == Integer.TYPE);//true

4,反射

反射就是把Java類中的各種成分映射成相應的java類。例如,一個java類中用一個Class對象來表示,

一個類中的組成部分:成員變量,方法,構造方法,包等等信息也是一個個的java類來表示,比搜狐java

類的class類顯然要提供一系列的方法,來獲得起其中的變量,方法,構造方法,修飾符,包等信息。這些

信息就是用相應的實例對象來表示。他們是Field,,Method,Contructor,Package等等。

1,Constructor

Constructor 類代表某個類中的一個構造方法。

得到某個類所有的構造方法:

Constructor [] constructors = String.class.getConstructors();
Constructor [] constructors1 = Class.forName("java.lang.String").getConstructors();

得到某一個構造方法:

Constructor constructor = String.class.getConstructor(StringBuffer.class);

//創建一個實例。
//普通的實例
String s1 = new String(new StringBuffer("abc"));
//反射創建實例
String s2 = String.class.getConstructor(StringBuffer.class).newInstance(new StringBuffer("abc"));

Field類代表某個類的一個成員變量。

例如:

ReflectPoint 這個類中有了兩個成員變量,x,y但x屬於私有的,所以後面的操作會有所不一樣。

兩個成員方法,一個無參的,一個有兩個參數的。

ReflectPoint reflectPoint  = new ReflectPoint(5, 7);

Field Y = reflectPoint.getClass().getField("y");
Object y = Y.get(reflectPoint);
System.out.println(y);
/*Field X = reflectPoint.getClass().getField("x");
Object x = X.get(reflectPoint);
System.out.println(x);
*/
Field X = reflectPoint.getClass().getDeclaredField("x");
X.setAccessible(true);
Object x = X.get(reflectPoint);
System.out.println(x);

2,一個小例子:將任意一個對象中的所有String類型的成員變量所對應字符串中內容的“b“改成”a“

public void changeValue(Object obj) throws  IllegalAccessException{

Field[] fields = obj.getClass().getFields();

for (Field field : fields) {
//這裏要用==,因爲比較的字節碼,當然也是可以用equals的,用==號會顯得技術牛。
if (field.getType()==String.class) {

String oldValue = (String) field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, oldValue);

}
}
}

3.Method類

Method 類代表某個類的一個成員方法

得到類中某一個方法
String s3 = "abcd";
Method charAt = String.class.getMethod("charAt", int.class);
//普通方法調用
char charAt2 = s3.charAt(1);
//反射方法調用
Object charAt3 = charAt.invoke(s3, 1);

如果傳遞給Method對象的invoke()方法的第一個參數爲null.這有着什麼樣的意義呢?說明該Method對象對應的是一個靜態方法!

4,數組的反射:

具有相同維數和元素類型的數據屬於同一類型,具有相同的Class實例對象。


5,關於讀取資源文件的方法和爲位置:


/*InputStream is = new FileInputStream("src/com/koal/config.properties");
Properties pro = new Properties();
pro.load(is);
System.out.println(pro.get("className"));*/
/*InputStream ins = Test_Path.class.getClassLoader().getResourceAsStream("com/koal/config.properties");
Properties pro = new Properties();
pro.load(ins);
System.out.println(pro.get("className"));*/
InputStream ins = Test_Path.class.getResourceAsStream("config.properties");
Properties pro = new Properties();
pro.load(ins);
System.out.println(pro.get("className"));








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章