java語言

當前位置 /首頁/計算機/java語言/列表

Java反射機制學習總結

一、什麼是反射機制

Java反射機制學習總結

簡單的來說,反射機制指的是程式在執行時能夠獲取自身的資訊。在java中,只要給定類的名字,那麼就可以通過反射機制來獲得類的所有資訊。

二、哪裡用到反射機制

有些時候,我們用過一些知識,但是並不知道它的專業術語是什麼,在剛剛學jdbc時用過一行程式碼, ame("s")nstance();但是那時候只知道那行程式碼是生成驅動物件例項,並不知道它的具體含義。聽了反射機制這節課後,才知道,原來這就是反射,現在很多開框架都用到反射機制,hibernate、struts都是用反射機制實現的。

三、反射機制的優點與缺點

為什麼要用反射機制?直接建立物件不就可以了嗎,這就涉及到了動態與靜態的概念,

靜態編譯:在編譯時確定型別,繫結物件,即通過。

動態編譯:執行時確定型別,繫結物件。動態編譯最大限度發揮了java的靈活性,體現了多型的應用,有以降低類之間的藕合性。

一句話,反射機制的優點就是可以實現動態建立物件和編譯,體現出很大的靈活性,特別是在J2EE的開發中它的靈活性就表現的十分明顯。比如,一個大型的軟體,不可能一次就把把它設計的很完美,當這個程式編譯後,釋出了,當發現需要更新某些功能時,我們不可能要使用者把以前的解除安裝,再重新安裝新的版本,假如這樣的話,這個軟體肯定是沒有多少人用的。採用靜態的話,需要把整個程式重新編譯一次才可以實現功能的更新,而採用反射機制的話,它就可以不用解除安裝,只需要在執行時才動態的建立和編譯,就可以實現該功能。

它的缺點是對效能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什麼並且它滿足我們的要求。這類操作總是慢於只直接執行相同的操作。

四、利用反射機制能獲得什麼資訊

一句話,類中有什麼資訊,它就可以獲得什麼資訊,不過前提是得知道類的名字,要不就沒有後文了首先得根據傳入的類的全名來建立Class物件。

Class c=ame("className");註明:className必須為全名,也就是得包含包名,比如,Info;

Object obj=nstance();//建立物件的例項

OK,有了物件就什麼都好辦了,想要什麼資訊就有什麼資訊了。

獲得建構函式的方法

Constructor getConstructor(Class[] params)//根據指定引數獲得public構造器

Constructor[] getConstructors()//獲得public的所有構造器

Constructor getDeclaredConstructor(Class[] params)//根據指定引數獲得public和非public的構造器

Constructor[] getDeclaredConstructors()//獲得public的所有構造器

獲得類方法的方法

Method getMethod(String name, Class[] params),根據方法名,引數型別獲得方法

Method[] getMethods()//獲得所有的public方法

Method getDeclaredMethod(String name, Class[] params)//根據方法名和引數型別,獲得public和非public的方法

Method[] getDeclaredMethods()//獲得所以的public和非public方法

獲得類中屬性的方法

Field getField(String name)//根據變數名得到相應的public變數

Field[] getFields()//獲得類中所以public的方法

Field getDeclaredField(String name)//根據方法名獲得public和非public變數

Field[] getDeclaredFields()//獲得類中所有的public和非public方法

常用的就這些,知道這些,其他的都好辦……

五、用反射機制能幹什麼事

剛開始在使用jdbc時侯,在編寫訪問資料庫時寫到想吐,有八個表,每個表都有增刪改查中操作,那時候還不知道有反射機制這個概念,所以就對不同的表建立不同的dao類,這樣不僅開發速率地,而且程式碼冗餘的厲害,最要命的是看著差不多的,然後直接複製修改,由於容易犯各種低階的錯誤(大小寫啊,多一個或少一個字母啊……),一個錯誤就可以讓你找半天。

有了java反射機制,什麼都好辦了,只需要寫一個dao類,四個方法,增刪改查,傳入不同的物件,就OK啦,無需為每一個表都建立dao類,反射機制會自動幫我們完成剩下的事情,這就是它的好處。說白了,反射機制就是專門幫我們做那些重複的有規則的事情,所以現在很多的自動生成程式碼的軟體就是運用反射機制來完成的,只要你按照規則輸入相關的引數,所以低階的程式設計師慢慢的就被抹殺了,為什麼?因為程式碼都不用寫了,隨便一個人都會開發,還要程式設計師幹什麼啊?所以我們只有一條出路,那就是努力努力再努力,成為高階程式設計師,專門開發傻瓜軟體,讓其他程式設計師 到 一邊涼快去,呵呵~

六、用反射機制實現對資料庫資料的增、查例子

基本原理;儲存資料時,把需要儲存的物件的屬性值全部取出來再拼湊sql語句查詢時,將查詢到的資料全部包裝成一個java物件。

遊戲規則:俗話說的好,無規矩不成方圓,特別是程式來說,它只能做有規則的事情,沒有規則的它幹不了,好,那就先定規則

1)資料庫的每一個表物件一個pojo類,表中的每一個欄位對應pojo類的.中的一個屬性。並且pojo類的名字和表的名字相同,屬性名和欄位名相同,大小寫沒有關係,因為資料庫一般不區分大小寫

2)為pojo類中的每一個屬性新增標準的set和get方法。

有了遊戲規則,那麼開始遊戲吧。

1、首先資料庫的有一個表,假設資料庫名稱為:blogsystem,裡面的一個表名userinfo。如圖:

2、建立對應的pojo類:

複製程式碼 程式碼如下:

package ;

public class UserInfo {

private int id;

private String name;

private String pwd;

private int age;

@Override

public String toString() {

return "UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="

+ age + "]";

}

public int getId() {

return id;

}

public void setId(int id) {

= id;

}

public String getName() {

return name;

}

public void setName(String name) {

= name;

}

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

= pwd;

}

public int getAge() {

return age;

}

public void setAge(int age) {

= age;

}

}

2、編寫獲得資料庫連線的工廠類:

複製程式碼 程式碼如下:

package ory;

import ection;

import erManager;

public class Connect2DBFactory {

public static Connection getDBConnection() {

Connection conn = null;

try {

ame("er");

String url = "jdbc:mysql://localhost:3306/blogsystem";

String user = "root";

String password = "netjava";

conn = onnection(url, user, password);

} catch (Exception e) {

tStackTrace();

}

return conn;

}

}

3、好戲開始啦,編寫操作資料庫的dao類

複製程式碼 程式碼如下:

package ion;

import d;

import od;

import ection;

import aredStatement;

import ltSet;

import xception;

import ement;

import yList;

import ;

import ect2DBFactory;

import Info;

public class NetJavaSession {

/**

* 解析出儲存物件的sql語句

*

* @param object

* :需要儲存的物件

* @return:儲存物件的sql語句

*/

public static String getSaveObjectSql(Object object) {

// 定義一個sql字串

String sql = " into ";

// 得到物件的類

Class c = lass();

// 得到物件中所有的方法

Method[] methods = ethods();

// 得到物件中所有的屬性

Field[] fields = ields();

// 得到物件類的名字

String cName = ame();

// 從類的名字中解析出表名

String tableName = tring(IndexOf(".") + 1,

th());

sql += tableName + "(";

ListmList = new ArrayList();

List vList = new ArrayList();

for (Method method : methods) {

String mName = ame();

if (tsWith("get") && !tsWith("getClass")) {

String fieldName = tring(3, th());

(fieldName);

tln("欄位名字----->" + fieldName);

try {

Object value = ke(object, null);

tln("執行方法返回的值:" + value);

if (value instanceof String) {

(""" + value + """);

tln("欄位值------>" + value);

} else {

(value);

}

} catch (Exception e) {

tStackTrace();

}

}

}

for (int i = 0; i < (); i++) {

if (i < () - 1) {

sql += (i) + ",";

} else {

sql += (i) + ") values(";

}

}

for (int i = 0; i < (); i++) {

if (i < () - 1) {

sql += (i) + ",";

} else {

sql += (i) + ")";

}

}

return sql;

}

public static List getDatasFromDB(String tableName, int Id) {

return null;

}

/**

* 將物件儲存到資料庫中

*

* @param object

* :需要儲存的物件

* @return:方法執行的結果;1:表示成功,0:表示失敗

*/

public int saveObject(Object object) {

Connection con = BConnection();

String sql = getSaveObjectSql(object);

try {

// Statement statement=(Statement) teStatement();

PreparedStatement psmt = areStatement(sql);

uteUpdate();

return 1;

} catch (SQLException e) {

tStackTrace();

return 0;

}

}

/**

* 從資料庫中取得物件

*

* @param arg0

* :物件所屬的類

* @param id

* :物件的id

* @return:需要查詢的物件

*/

public Object getObject(String className, int Id) {

// 得到表名字

String tableName = tring(IndexOf(".") + 1,

th());

// 根據類名來建立Class物件

Class c = null;

try {

c = ame(className);

} catch (ClassNotFoundException e1) {

tStackTrace();

}

// 拼湊查詢sql語句

String sql = "select * from " + tableName + " where Id=" + Id;

tln("查詢sql語句:" + sql);

// 獲得資料庫連結

Connection con = BConnection();

// 建立類的例項

Object obj = null;

try {

Statement stm = teStatement();

// 得到執行查尋語句返回的結果集

ResultSet set = uteQuery(sql);

// 得到物件的方法陣列

Method[] methods = ethods();

// 遍歷結果集

while (()) {

obj = nstance();

// 遍歷物件的方法

for (Method method : methods) {

String methodName = ame();

// 如果物件的方法以set開頭

if (tsWith("set")) {

// 根據方法名字得到資料表格中欄位的名字

String columnName = tring(3,

th());

// 得到方法的引數型別

Class[] parmts = arameterTypes();

if (parmts[0] == s) {

// 如果引數為String型別,則從結果集中按照列名取得對應的值,並且執行改set方法

ke(obj, tring(columnName));

}

if (parmts[0] == s) {

ke(obj, nt(columnName));

}

}

}

}

} catch (Exception e) {

tStackTrace();

}

return obj;

}

}

4、開始測試效果怎麼樣:

複製程式碼 程式碼如下:

package er;

import Info;

import avaSession;

public class Tester {

public static void main(String args[]) {

//獲得NetJavaSession物件

NetJavaSession session = new NetJavaSession();

//建立一個UserInfo物件

UserInfo user = new UserInfo();

//設定物件的屬性

d(6988);

ge(44);

wd("pwd");

ame("champion");

//將物件儲存到資料庫中

String sql = aveObjectSql(user);

tln("儲存物件的sql語句:" + sql);

//查詢物件

UserInfo userInfo = (UserInfo) bject(

"Info", 6988);

tln("獲取到的資訊:" + userInfo);

}

}

5、打印出來的結果:

七、總節一下

總的來說,java反射機制是一個很好用的東西,用它可以解決很多死的東西,因為反射機制的靈活行很大,有了他,我們就不要花太多的時間來寫操做資料庫的程式碼了,而是方法更多的時間在專案的邏輯功能上,這個可以很大的減少開發時間,而且程式碼的可讀性好。先在的很多開源框架都是才用的反射機制,它只要配置檔案,然後按規則來呼叫他的方法就可以了。

TAG標籤:學習 機制 JAVA #