亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java反射機制的學習總結

2019-11-26 15:58:17
字體:
來源:轉載
供稿:網友

一、什么是反射機制
簡單的來說,反射機制指的是程序在運行時能夠獲取自身的信息。在java中,只要給定類的名字,那么就可以通過反射機制來獲得類的所有信息。

二、哪里用到反射機制
有些時候,我們用過一些知識,但是并不知道它的專業術語是什么,在剛剛學jdbc時用過一行代碼, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那時候只知道那行代碼是生成驅動對象實例,并不知道它的具體含義。聽了反射機制這節課后,才知道,原來這就是反射,現在很多開框架都用到反射機制,hibernate、struts都是用反射機制實現的。

三、反射機制的優點與缺點
為什么要用反射機制?直接創建對象不就可以了嗎,這就涉及到了動態與靜態的概念,
靜態編譯:在編譯時確定類型,綁定對象,即通過。

動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多態的應用,有以降低類之間的藕合性。

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

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

四、利用反射機制能獲得什么信息
一句話,類中有什么信息,它就可以獲得什么信息,不過前提是得知道類的名字,要不就沒有后文了首先得根據傳入的類的全名來創建Class對象。

Class c=Class.forName("className");注明:className必須為全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();//創建對象的實例
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 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;
}

}

2、編寫獲得數據庫連接的工廠類:
復制代碼 代碼如下:

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;
    }
}

3、好戲開始啦,編寫操作數據庫的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 {
    /**
     * 解析出保存對象的sql語句
     *
     * @param object
     *            :需要保存的對象
     * @return:保存對象的sql語句
     */
    public static String getSaveObjectSql(Object object) {
        // 定義一個sql字符串
        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;

    }

    /**
     * 將對象保存到數據庫中
     *
     * @param object
     *            :需要保存的對象
     * @return:方法執行的結果;1:表示成功,0:表示失敗
     */
    public int saveObject(Object object) {
        Connection con = Connect2DBFactory.getDBConnection();
        String sql = getSaveObjectSql(object);
        try {
            // Statement statement=(Statement) con.createStatement();
            PreparedStatement psmt = con.prepareStatement(sql);
            psmt.executeUpdate();
            return 1;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 從數據庫中取得對象
     *
     * @param arg0
     *            :對象所屬的類
     * @param id
     *            :對象的id
     * @return:需要查找的對象
     */
    public Object getObject(String className, int Id) {
        // 得到表名字
        String tableName = className.substring(className.lastIndexOf(".") + 1,
                className.length());
        // 根據類名來創建Class對象
        Class c = null;
        try {
            c = Class.forName(className);

        } catch (ClassNotFoundException e1) {

            e1.printStackTrace();
        }
        // 拼湊查詢sql語句
        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();
                    // 如果對象的方法以set開頭
                    if (methodName.startsWith("set")) {
                        // 根據方法名字得到數據表格中字段的名字
                        String columnName = methodName.substring(3,
                                methodName.length());
                        // 得到方法的參數類型
                        Class[] parmts = method.getParameterTypes();
                        if (parmts[0] == String.class) {
                            // 如果參數為String類型,則從結果集中按照列名取得對應的值,并且執行改set方法
                            method.invoke(obj, set.getString(columnName));
                        }
                        if (parmts[0] == int.class) {
                            method.invoke(obj, set.getInt(columnName));
                        }
                    }

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

4、開始測試效果怎么樣:
復制代碼 代碼如下:

package cn.netjava.tester;

import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;

public class Tester {
    public static void main(String args[]) {
        //獲得NetJavaSession對象
        NetJavaSession session = new NetJavaSession();
        //創建一個UserInfo對象
        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);

    }
}

5、打印出來的結果:

七、總節一下
總的來說,java反射機制是一個很好用的東西,用它可以解決很多死的東西,因為反射機制的靈活行很大,有了他,我們就不要花太多的時間來寫操做數據庫的代碼了,而是方法更多的時間在項目的邏輯功能上,這個可以很大的減少開發時間,而且代碼的可讀性好。先在的很多開源框架都是才用的反射機制,它只要配置文件,然后按規則來調用他的方法就可以了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩欧美视频在线| 97人人模人人爽人人喊中文字| 日韩成人激情在线| 欧美有码在线观看| 国产精品成人久久久久| 亚洲福利视频久久| 色偷偷噜噜噜亚洲男人的天堂| 国产亚洲一级高清| 久久免费视频在线观看| 2018日韩中文字幕| 91久久精品视频| 亚洲欧美日韩中文在线制服| 夜夜嗨av色一区二区不卡| 日韩高清电影好看的电视剧电影| 欧美激情视频在线免费观看 欧美视频免费一| 国产精品嫩草影院久久久| 亚洲日本中文字幕免费在线不卡| 国产精品扒开腿做爽爽爽视频| 色av吧综合网| 精品久久久久久久久久久久| 亚洲国产精品免费| 亚洲一区国产精品| 精品久久久国产精品999| 一区二区国产精品视频| 日韩精品视频在线免费观看| 欧美精品video| 欧美日韩裸体免费视频| 日韩精品亚洲视频| 最近2019中文字幕第三页视频| 亚洲肉体裸体xxxx137| 日韩激情av在线免费观看| 98视频在线噜噜噜国产| 亚洲欧洲国产精品| 伦理中文字幕亚洲| 九九久久久久久久久激情| 日韩视频―中文字幕| 亚洲人成网7777777国产| 午夜精品www| 97超碰国产精品女人人人爽| 久久中文精品视频| 日韩有码在线播放| 国产美女直播视频一区| 亚洲成av人影院在线观看| 亚洲国产欧美一区二区三区同亚洲| 亚洲男女自偷自拍图片另类| 国产欧美精品日韩| 日韩电影视频免费| 国产91av在线| 国产欧美 在线欧美| 国产高清在线不卡| 欧美色另类天堂2015| 国产精品xxxxx| 精品在线欧美视频| 视频在线观看一区二区| 欧美巨猛xxxx猛交黑人97人| 国产一级揄自揄精品视频| 欧美国产日韩免费| 欧美国产精品人人做人人爱| 久久综合免费视频影院| 欧美日韩另类字幕中文| 久久精品久久久久| 国内精品伊人久久| 成人av在线网址| 狠狠爱在线视频一区| 最近中文字幕日韩精品| 久久免费观看视频| 国产精品久久二区| 日韩中文字幕在线视频播放| 大桥未久av一区二区三区| 97在线视频一区| 91久久久久久久| 欧美性猛交99久久久久99按摩| 国语对白做受69| 国产精品久久久久国产a级| 亚洲色图15p| 亚洲国产成人久久综合| 亚洲自拍偷拍视频| 久久久女女女女999久久| 国产精品v日韩精品| 日本免费在线精品| 亚洲www永久成人夜色| 国产精品video| 精品国产区一区二区三区在线观看| 日韩欧美黄色动漫| 久久精品成人一区二区三区| 日韩av影片在线观看| 亚洲电影第1页| 国产精品网站大全| 26uuu久久噜噜噜噜| 国产精品视频公开费视频| 久久久噜噜噜久噜久久| 亚洲自拍偷拍视频| 日韩欧美一区二区三区| 亚洲老板91色精品久久| 成人黄色大片在线免费观看| 成人av在线亚洲| 国产精品美女免费看| 国产精品中文字幕在线| 日韩精品极品在线观看播放免费视频| 日本精品久久中文字幕佐佐木| 欧美中文在线观看国产| 国产欧美日韩综合精品| 精品在线小视频| 欧美黑人狂野猛交老妇| 欧美成人一二三| 国内精品小视频| 国产精品69久久久久| 欧美视频一区二区三区…| 精品日韩视频在线观看| 国产精品h片在线播放| 亚洲精品在线不卡| 国产精品日韩专区| 欧美福利视频在线| 91精品久久久久久久久久| 97精品国产97久久久久久| 中文精品99久久国产香蕉| 国产一区二区三区三区在线观看| 亚洲精品天天看| 国产精品久久久久久久久久三级| 亚洲激情视频在线观看| 欧美乱大交xxxxx| 色综合老司机第九色激情| 色综合老司机第九色激情| 精品国产一区二区三区久久狼黑人| 久久全球大尺度高清视频| 97涩涩爰在线观看亚洲| 大伊人狠狠躁夜夜躁av一区| 精品国产成人在线| 欧美理论电影在线观看| 亚洲欧洲激情在线| 91老司机精品视频| 欧美视频一二三| 欧美激情精品久久久| 精品国产拍在线观看| 欧美性生交大片免网| 九九热精品视频国产| 中文字幕在线看视频国产欧美| 国产精品91在线| 欧美成人h版在线观看| 亚洲成人av在线| 国产成人精品视频在线观看| 国a精品视频大全| 久久精品国产电影| 黑人巨大精品欧美一区二区| 亚洲人成电影在线| 九九精品在线观看| 国产精品一区二区久久久| 欧美精品免费在线观看| 热草久综合在线| 国产精品高潮呻吟久久av黑人| 亚洲成人a级网| 欧美视频免费在线| 欧美精品精品精品精品免费| 这里精品视频免费| 精品视频—区二区三区免费| 精品国产91久久久久久老师| 欧美成人午夜影院| 国产一区二区香蕉| 久久九九免费视频| 国产一区二区动漫| 成人黄色影片在线| 91精品国产91久久久久久最新| 色偷偷亚洲男人天堂| 国产精品免费一区二区三区都可以|