1、什麼是反射機制
簡單的來講,反射機制指的是程序在運行時可以獲取自身的信息。在java中,只要給定類的名字,
那麼就能夠經過反射機制來得到類的全部信息。
2、哪裏用到反射機制
有些時候,咱們用過一些知識,可是並不知道它的專業術語是什麼,在剛剛學jdbc時用過一行代碼,
Class.forName("com.mysql.jdbc.Driver.class").newInstance();可是那時候只知道那行代碼是生成
驅動對象實例,並不知道它的具體含義。聽了反射機制這節課後,才知道,原來這就是反射,如今不少開
框架都用到反射機制,hibernate、struts都是用反射機制實現的。
3、反射機制的優勢與缺點
爲何要用反射機制?直接建立對象不就能夠了嗎,這就涉及到了動態與靜態的概念,
靜態編譯:在編譯時肯定類型,綁定對象,即經過。
動態編譯:運行時肯定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多
態的應用,有以下降類之間的藕合性。
一句話,反射機制的優勢就是能夠實現動態建立對象和編譯,體現出很大的靈活性,特別是在J2EE的開發中
它的靈活性就表現的十分明顯。好比,一個大型的軟件,不可能一次就把把它設計的很完美,當這個程序編
譯後,發佈了,當發現須要更新某些功能時,咱們不可能要用戶把之前的卸載,再從新安裝新的版本,假如
這樣的話,這個軟件確定是沒有多少人用的。採用靜態的話,須要把整個程序從新編譯一次才能夠實現功能
的更新,而採用反射機制的話,它就能夠不用卸載,只須要在運行時才動態的建立和編譯,就能夠實現該功
能。
它的缺點是對性能有影響。使用反射基本上是一種解釋操做,咱們能夠告訴JVM,咱們但願作什麼而且它
知足咱們的要求。這類操做老是慢於只直接執行相同的操做。
4、利用反射機制能得到什麼信息
一句話,類中有什麼信息,它就能夠得到什麼信息,不過前提是得知道類的名字,要不就沒有後文了
首先得根據傳入的類的全名來建立Class對象。
Class c=Class.forName("className");註明:className必須爲全名,也就是得包含包名,好比,cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();//建立對象的實例
OK,有了對象就什麼都好辦了,想要什麼信息就有什麼信息了。
得到構造函數的方法
Constructor getConstructor(Class[] params)//根據指定參數得到public構造器java
Constructor[] getConstructors()//得到public的全部構造器mysql
Constructor getDeclaredConstructor(Class[] params)//根據指定參數得到public和非public的構造器程序員
Constructor[] getDeclaredConstructors()//得到public的全部構造器
得到類方法的方法
Method getMethod(String name, Class[] params),根據方法名,參數類型得到方法sql
Method[] getMethods()//得到全部的public方法數據庫
Method getDeclaredMethod(String name, Class[] params)//根據方法名和參數類型,得到public和非public的方法數組
Method[] getDeclaredMethods()//得到因此的public和非public方法
得到類中屬性的方法
Field getField(String name)//根據變量名獲得相應的public變量session
Field[] getFields()//得到類中因此public的方法框架
Field getDeclaredField(String name)//根據方法名得到public和非public變量ide
Field[] getDeclaredFields()//得到類中全部的public和非public方法
經常使用的就這些,知道這些,其餘的都好辦……
5、用反射機制能幹什麼事
剛開始在使用jdbc時侯,在編寫訪問數據庫時寫到想吐,有八個表,每一個表都有增刪改查中操做
那時候還不知道有反射機制這個概念,因此就對不一樣的表建立不一樣的dao類,這樣不只開發速率地,並且代碼
冗餘的厲害,最要命的是看着差很少的,而後直接複製修改,因爲容易犯各類低級的錯誤(大小寫啊,多一
個或少一個字母啊……),一個錯誤就可讓你找半天。
有了java反射機制,什麼都好辦了,只須要寫一個dao類,四個方法,增刪改查,傳入不一樣的對象,就OK啦,
無需爲每個表都建立dao類,反射機制會自動幫咱們完成剩下的事情,這就是它的好處。說白了,反射機制就是專門
幫咱們作那些重複的有規則的事情,因此如今不少的自動生成代碼的軟件就是運用反射機制來完成的,只要你按照規則
輸入相關的參數,因此低級的程序員慢慢的就被抹殺了,爲何?由於代碼都不用寫了,隨便一我的都會開發,還要程
序員幹什麼啊?因此咱們只有一條出路,那就是努力努力再努力,成爲高級程序員,專門開發傻瓜軟件,讓其餘程序員 到 一邊涼快去,呵呵~
6、用反射機制實現對數據庫數據的增、查例子
基本原理;保存數據時,把須要保存的對象的屬性值所有取出來再拼湊sql語句
查詢時,將查詢到的數據所有包裝成一個java對象。
遊戲規則:俗話說的好,無規矩不成方圓,特別是程序來講,它只能作有規則的事情,沒有規則的它幹不了,好,那就
先定規則
1)數據庫的每個表對象一個pojo類,表中的每個字段對應pojo類的中的一個屬性。
而且pojo類的名字和表的名字相同,屬性名和字段名相同,大小寫沒有關係,由於數據庫通常不區分大小寫
2)爲pojo類中的每個屬性添加標準的set和get方法。
有了遊戲規則,那麼開始遊戲吧。函數
2)爲pojo類中的每個屬性添加標準的set和get方法。
有了遊戲規則,那麼開始遊戲吧。
一、首先數據庫的有一個表,假設數據庫名稱爲:blogsystem,裏面的一個表名userinfo。如圖:
![](http://static.javashuo.com/static/loading.gif)
二、建立對應的pojo類:
- package cn.netjava.pojo;
-
- 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) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPwd() {
- return pwd;
- }
- public void setPwd(String pwd) {
- this.pwd = pwd;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
-
- }
二、編寫得到數據庫鏈接的工廠類:
- package cn.netjava.factory;
-
- import java.sql.Connection;
- import java.sql.DriverManager;
-
- public class Connect2DBFactory {
- public static Connection getDBConnection() {
- Connection conn = null;
- try {
- Class.forName("com.mysql.jdbc.Driver");
- String url = "jdbc:mysql://localhost:3306/blogsystem";
- String user = "root";
- String password = "netjava";
- conn = DriverManager.getConnection(url, user, password);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return conn;
- }
- }
三、好戲開始啦,編寫操做數據庫的dao類
- package cn.netjava.session;
-
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.ArrayList;
- import java.util.List;
-
- import cn.netjava.factory.Connect2DBFactory;
- import cn.netjava.pojo.UserInfo;
-
- public class NetJavaSession {
-
- public static String getSaveObjectSql(Object object) {
-
- String sql = "insert into ";
-
- Class c = object.getClass();
-
- Method[] methods = c.getMethods();
-
- Field[] fields = c.getFields();
-
- String cName = c.getName();
-
- String tableName = cName.substring(cName.lastIndexOf(".") + 1,
- cName.length());
- sql += tableName + "(";
- List<String> mList = new ArrayList<String>();
- List vList = new ArrayList();
- for (Method method : methods) {
- String mName = method.getName();
- if (mName.startsWith("get") && !mName.startsWith("getClass")) {
- String fieldName = mName.substring(3, mName.length());
- mList.add(fieldName);
- System.out.println("字段名字----->" + fieldName);
- try {
- Object value = method.invoke(object, null);
- System.out.println("執行方法返回的值:" + value);
- if (value instanceof String) {
- vList.add("\"" + value + "\"");
- System.out.println("字段值------>" + value);
- } else {
- vList.add(value);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- for (int i = 0; i < mList.size(); i++) {
- if (i < mList.size() - 1) {
- sql += mList.get(i) + ",";
- } else {
- sql += mList.get(i) + ") values(";
- }
- }
- for (int i = 0; i < vList.size(); i++) {
- if (i < vList.size() - 1) {
- sql += vList.get(i) + ",";
- } else {
- sql += vList.get(i) + ")";
- }
- }
-
- return sql;
- }
-
- public static List getDatasFromDB(String tableName, int Id) {
-
- return null;
-
- }
-
-
- public int saveObject(Object object) {
- Connection con = Connect2DBFactory.getDBConnection();
- String sql = getSaveObjectSql(object);
- try {
-
- PreparedStatement psmt = con.prepareStatement(sql);
- psmt.executeUpdate();
- return 1;
- } catch (SQLException e) {
- e.printStackTrace();
- return 0;
- }
- }
-
-
- public Object getObject(String className, int Id) {
-
- String tableName = className.substring(className.lastIndexOf(".") + 1,
- className.length());
-
- Class c = null;
- try {
- c = Class.forName(className);
-
- } catch (ClassNotFoundException e1) {
-
- e1.printStackTrace();
- }
-
- String sql = "select * from " + tableName + " where Id=" + Id;
- System.out.println("查找sql語句:" + sql);
-
- Connection con = Connect2DBFactory.getDBConnection();
-
- Object obj = null;
- try {
-
- Statement stm = con.createStatement();
-
- ResultSet set = stm.executeQuery(sql);
-
- Method[] methods = c.getMethods();
-
- while (set.next()) {
- obj = c.newInstance();
-
- for (Method method : methods) {
- String methodName = method.getName();
-
- if (methodName.startsWith("set")) {
-
- String columnName = methodName.substring(3,
- methodName.length());
-
- Class[] parmts = method.getParameterTypes();
- if (parmts[0] == String.class) {
-
- method.invoke(obj, set.getString(columnName));
- }
- if (parmts[0] == int.class) {
- method.invoke(obj, set.getInt(columnName));
- }
- }
-
- }
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return obj;
- }
- }
四、開始測試效果怎麼樣:
- package cn.netjava.tester;
-
- import cn.netjava.pojo.UserInfo;
- import cn.netjava.session.NetJavaSession;
-
- public class Tester {
- public static void main(String args[]) {
-
- NetJavaSession session = new NetJavaSession();
-
- UserInfo user = new UserInfo();
-
- user.setId(6988);
- user.setAge(44);
- user.setPwd("pwd");
- user.setName("champion");
-
- String sql = session.getSaveObjectSql(user);
- System.out.println("保存對象的sql語句:" + sql);
-
- UserInfo userInfo = (UserInfo) session.getObject(
- "cn.netjava.pojo.UserInfo", 6988);
- System.out.println("獲取到的信息:" + userInfo);
-
- }
- }
五、打印出來的結果:
![](http://static.javashuo.com/static/loading.gif)
7、總節一下
總的來講,java反射機制是一個很好用的東西,用它能夠解決不少死的東西,由於反射機制的靈活行很大,有了他,咱們就不要花太多的時間來寫操作數據庫的 代碼了,而是方法更多的時間在項目的邏輯功能上,這個能夠很大的減小開發時間,並且代碼的可讀性好。先在的不少開源框架都是才用的反射機制,它只要配置文 件,而後按規則來調用他的方法就能夠了。
轉載地址:http://champion-netjava-163-com.iteye.com/blog/982080