一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java反射機制的學(xué)習(xí)總結(jié)

Java反射機制的學(xué)習(xí)總結(jié)

2019-10-14 13:57java開發(fā)網(wǎng) Java教程

總的來說,java反射機制是一個很好用的東西,用它可以解決很多死的東西,因為反射機制的靈活行很大,有了他,我們就不要花太多的時間來寫操做數(shù)據(jù)庫的代碼了,而是方法更多的時間在項目的邏輯功能上,這個可以很大的減少

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

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

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

動態(tài)編譯:運行時確定類型,綁定對象。動態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多態(tài)的應(yīng)用,有以降低類之間的藕合性。 

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

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

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

Class c=Class.forName("className");注明:className必須為全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo; 
Object obj=c.newInstance();//創(chuàng)建對象的實例 
OK,有了對象就什么都好辦了,想要什么信息就有什么信息了。   
獲得構(gòu)造函數(shù)的方法 
Constructor getConstructor(Class[] params)//根據(jù)指定參數(shù)獲得public構(gòu)造器

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

Constructor getDeclaredConstructor(Class[] params)//根據(jù)指定參數(shù)獲得public和非public的構(gòu)造器

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

獲得類方法的方法 
Method getMethod(String name, Class[] params),根據(jù)方法名,參數(shù)類型獲得方法

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

Method getDeclaredMethod(String name, Class[] params)//根據(jù)方法名和參數(shù)類型,獲得public和非public的方法

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

獲得類中屬性的方法 
Field getField(String name)//根據(jù)變量名得到相應(yīng)的public變量

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

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

Field[] getDeclaredFields()//獲得類中所有的public和非public方法 
常用的就這些,知道這些,其他的都好辦…… 

五、用反射機制能干什么事 
剛開始在使用jdbc時侯,在編寫訪問數(shù)據(jù)庫時寫到想吐,有八個表,每個表都有增刪改查中操作,那時候還不知道有反射機制這個概念,所以就對不同的表創(chuàng)建不同的dao類,這樣不僅開發(fā)速率地,而且代碼冗余的厲害,最要命的是看著差不多的,然后直接復(fù)制修改,由于容易犯各種低級的錯誤(大小寫啊,多一個或少一個字母啊……),一個錯誤就可以讓你找半天。

有了java反射機制,什么都好辦了,只需要寫一個dao類,四個方法,增刪改查,傳入不同的對象,就OK啦,無需為每一個表都創(chuàng)建dao類,反射機制會自動幫我們完成剩下的事情,這就是它的好處。說白了,反射機制就是專門幫我們做那些重復(fù)的有規(guī)則的事情,所以現(xiàn)在很多的自動生成代碼的軟件就是運用反射機制來完成的,只要你按照規(guī)則輸入相關(guān)的參數(shù),所以低級的程序員慢慢的就被抹殺了,為什么?因為代碼都不用寫了,隨便一個人都會開發(fā),還要程序員干什么啊?所以我們只有一條出路,那就是努力努力再努力,成為高級程序員,專門開發(fā)傻瓜軟件,讓其他程序員  到 一邊涼快去,呵呵~

六、用反射機制實現(xiàn)對數(shù)據(jù)庫數(shù)據(jù)的增、查例子 
基本原理;保存數(shù)據(jù)時,把需要保存的對象的屬性值全部取出來再拼湊sql語句查詢時,將查詢到的數(shù)據(jù)全部包裝成一個java對象。 

游戲規(guī)則:俗話說的好,無規(guī)矩不成方圓,特別是程序來說,它只能做有規(guī)則的事情,沒有規(guī)則的它干不了,好,那就先定規(guī)則 
1)數(shù)據(jù)庫的每一個表對象一個pojo類,表中的每一個字段對應(yīng)pojo類的中的一個屬性。并且pojo類的名字和表的名字相同,屬性名和字段名相同,大小寫沒有關(guān)系,因為數(shù)據(jù)庫一般不區(qū)分大小寫  

2)為pojo類中的每一個屬性添加標(biāo)準(zhǔn)的set和get方法。 
有了游戲規(guī)則,那么開始游戲吧。

1、首先數(shù)據(jù)庫的有一個表,假設(shè)數(shù)據(jù)庫名稱為:blogsystem,里面的一個表名userinfo。如圖:

Java反射機制的學(xué)習(xí)總結(jié)
2、創(chuàng)建對應(yīng)的pojo類:

復(fù)制代碼代碼如下:

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、編寫獲得數(shù)據(jù)庫連接的工廠類:

復(fù)制代碼代碼如下:

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、好戲開始啦,編寫操作數(shù)據(jù)庫的dao類

復(fù)制代碼代碼如下:

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("執(zhí)行方法返回的值:" + 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; 

    } 

    /**
     * 將對象保存到數(shù)據(jù)庫中 
     * 
     * @param object
     *            :需要保存的對象 
     * @return:方法執(zhí)行的結(jié)果;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; 
        } 
    } 

    /**
     * 從數(shù)據(jù)庫中取得對象 
     * 
     * @param arg0 
     *            :對象所屬的類 
     * @param id
     *            :對象的id
     * @return:需要查找的對象 
     */
    public Object getObject(String className, int Id) { 
        // 得到表名字 
        String tableName = className.substring(className.lastIndexOf(".") + 1, 
                className.length()); 
        // 根據(jù)類名來創(chuàng)建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); 
        // 獲得數(shù)據(jù)庫鏈接 
        Connection con = Connect2DBFactory.getDBConnection(); 
        // 創(chuàng)建類的實例 
        Object obj = null; 
        try { 

            Statement stm = con.createStatement(); 
            // 得到執(zhí)行查尋語句返回的結(jié)果集 
            ResultSet set = stm.executeQuery(sql); 
            // 得到對象的方法數(shù)組 
            Method[] methods = c.getMethods(); 
            // 遍歷結(jié)果集 
            while (set.next()) { 
                obj = c.newInstance(); 
                // 遍歷對象的方法 
                for (Method method : methods) { 
                    String methodName = method.getName(); 
                    // 如果對象的方法以set開頭 
                    if (methodName.startsWith("set")) { 
                        // 根據(jù)方法名字得到數(shù)據(jù)表格中字段的名字 
                        String columnName = methodName.substring(3, 
                                methodName.length()); 
                        // 得到方法的參數(shù)類型 
                        Class[] parmts = method.getParameterTypes(); 
                        if (parmts[0] == String.class) { 
                            // 如果參數(shù)為String類型,則從結(jié)果集中按照列名取得對應(yīng)的值,并且執(zhí)行改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、開始測試效果怎么樣:

復(fù)制代碼代碼如下:

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(); 
        //創(chuàng)建一個UserInfo對象 
        UserInfo user = new UserInfo(); 
        //設(shè)置對象的屬性 
        user.setId(6988); 
        user.setAge(44); 
        user.setPwd("pwd"); 
        user.setName("champion"); 
        //將對象保存到數(shù)據(jù)庫中 
        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、打印出來的結(jié)果:

Java反射機制的學(xué)習(xí)總結(jié)

 

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 三上悠亚精品专区久久 | 日本xxx片免费高清在线 | 草女人逼| 久久99国产精品二区不卡 | 闺蜜调教我做她的脚奴 | 亚洲午夜久久久 | 国产亚洲精品一区久久 | 日韩精选在线 | 九九国产视频 | 青青青青在线视频 | 国产精品女主播大秀在线 | 国产夜趣福利第一视频 | sedog在线长片 | 湿好紧太硬了我太爽了 | 波多野结衣之高校教师 | hezyo加勒比一区二区三区 | 欧美一级视 | 日本午夜影院 | 免费黄色片在线观看 | 91超级碰 | 精品国产一区二区三区久久久狼 | 亚洲欧洲色图 | 99精品久久99久久久久久 | 2012年免费中文视频 | 欧美精品日韩一区二区三区 | 国产欧美久久一区二区 | 精品一区二区三区 不卡高清 | 天天做天天爱天天综合网 | 男同精品视频免费观看网站 | 国产真实一区二区三区 | 欧美人畜 | 调教开发新婚娇妻放荡 | 欧美精品一国产成人性影视 | 99热这里只精品99re66 | 99精品视频免费观看 | 1024在线视频精品免费 | 成年人福利视频 | 丝瓜香蕉视频 | www.四色 | 国产情侣啪啪 | 乳色吐息讲的是什么 |