<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          華為二面:說一下Java反射機(jī)制的應(yīng)用場(chǎng)景

          共 5548字,需瀏覽 12分鐘

           ·

          2021-08-25 16:13

          來源:sf.gg/a/1190000010162647

          近期在維護(hù)公司項(xiàng)目的時(shí)候遇到一個(gè)問題,因?yàn)閷?shí)體類中的 set 方法涉及到了業(yè)務(wù)邏輯,因此在給對(duì)象賦值的過程中不能夠使用 set 方法,為了實(shí)現(xiàn)功能,所以采用了反射的機(jī)制給對(duì)象屬性賦值,借此機(jī)會(huì)也了解了反射的一些具體用法和使用場(chǎng)景,分以下兩點(diǎn)對(duì)反射進(jìn)行分析:

          • 反射的優(yōu)勢(shì)和劣勢(shì)
          • 反射的應(yīng)用場(chǎng)景


          反射的優(yōu)勢(shì)和劣勢(shì)


          個(gè)人理解,反射機(jī)制實(shí)際上就是上帝模式,如果說方法的調(diào)用是 Java 正確的打開方式,那反射機(jī)制就是上帝偷偷開的后門,只要存在對(duì)應(yīng)的class,一切都能夠被調(diào)用。

          那上帝為什么要打開這個(gè)后門呢?這涉及到了靜態(tài)和動(dòng)態(tài)的概念


          兩者的區(qū)別在于,動(dòng)態(tài)編譯可以最大程度地支持多態(tài),而多態(tài)最大的意義在于降低類的耦合性,因此反射的優(yōu)點(diǎn)就很明顯了:解耦以及提高代碼的靈活性。

          因此,反射的優(yōu)勢(shì)和劣勢(shì)分別在于:

          • 優(yōu)勢(shì)
          • 運(yùn)行期類型的判斷,動(dòng)態(tài)類加載:提高代碼靈活度

          • 劣勢(shì)
          • 性能瓶頸:反射相當(dāng)于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多


          反射的應(yīng)用場(chǎng)景


          在我們平時(shí)的項(xiàng)目開發(fā)過程中,基本上很少會(huì)直接使用到反射機(jī)制,但這不能說明反射機(jī)制沒有用,實(shí)際上有很多設(shè)計(jì)、開發(fā)都與反射機(jī)制有關(guān),例如模塊化的開發(fā),通過反射去調(diào)用對(duì)應(yīng)的字節(jié)碼;動(dòng)態(tài)代理設(shè)計(jì)模式也采用了反射機(jī)制,還有我們?nèi)粘J褂玫?Spring/Hibernate 等框架,也是利用CGLIB 反射機(jī)制才得以實(shí)現(xiàn),下面就舉例最常見的兩個(gè)例子,來說明反射機(jī)制的強(qiáng)大之處:

          • JDBC 的數(shù)據(jù)庫的連接

          在JDBC 的操作中,如果要想進(jìn)行數(shù)據(jù)庫的連接,則必須按照以上的幾步完成

          1. 通過Class.forName()加載數(shù)據(jù)庫的驅(qū)動(dòng)程序 (通過反射加載,前提是引入相關(guān)了Jar包)
          2. 通過 DriverManager 類進(jìn)行數(shù)據(jù)庫的連接,連接的時(shí)候要輸入數(shù)據(jù)庫的連接地址、用戶名、密碼
          3. 通過Connection 接口接收連接
          public class ConnectionJDBC {
          /** * @param args */ //驅(qū)動(dòng)程序就是之前在classpath中配置的JDBC的驅(qū)動(dòng)程序的JAR 包中 public static final String DBDRIVER = "com.mysql.jdbc.Driver"; //連接地址是由各個(gè)數(shù)據(jù)庫生產(chǎn)商單獨(dú)提供的,所以需要單獨(dú)記住 public static final String DBURL = "jdbc:mysql://localhost:3306/test"; //連接數(shù)據(jù)庫的用戶名 public static final String DBUSER = "root"; //連接數(shù)據(jù)庫的密碼 public static final String DBPASS = "";

          public static void main(String[] args) throws Exception { Connection con = null; //表示數(shù)據(jù)庫的連接對(duì)象 Class.forName(DBDRIVER); //1、使用CLASS 類加載驅(qū)動(dòng)程序 ,反射機(jī)制的體現(xiàn) con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、連接數(shù)據(jù)庫 System.out.println(con); con.close(); // 3、關(guān)閉數(shù)據(jù)庫 }

          • Spring 框架的使用

          在 Java的反射機(jī)制在做基礎(chǔ)框架的時(shí)候非常有用,行內(nèi)有一句這樣的老話:反射機(jī)制是Java框架的基石。一般應(yīng)用層面很少用,不過這種東西,現(xiàn)在很多開源框架基本都已經(jīng)封裝好了,自己基本用不著寫。

          典型的除了hibernate之外,還有spring也用到很多反射機(jī)制。最經(jīng)典的就是xml的配置模式。

          Spring 通過 XML 配置模式裝載 Bean 的過程:

          1. 將程序內(nèi)所有 XML 或 Properties 配置文件加載入內(nèi)存中
          2. Java類里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類的字節(jié)碼字符串以及相關(guān)的屬性信息
          3. 使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類的Class實(shí)例
          4. 動(dòng)態(tài)配置實(shí)例的屬性

          Spring這樣做的好處是:


          模擬 Spring 加載 XML 配置文件:
          public class BeanFactory {       private Map<String, Object> beanMap = new HashMap<String, Object>();       /**       * bean工廠的初始化.       * @param xml xml配置文件       */       public void init(String xml) {              try {                     //讀取指定的配置文件                     SAXReader reader = new SAXReader();                     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();                     //從class目錄下獲取指定的xml文件                     InputStream ins = classLoader.getResourceAsStream(xml);                     Document doc = reader.read(ins);                     Element root = doc.getRootElement();                     Element foo;
          //遍歷bean for (Iterator i = root.elementIterator("bean"); i.hasNext();) { foo = (Element) i.next(); //獲取bean的屬性id和class Attribute id = foo.attribute("id"); Attribute cls = foo.attribute("class");
          //利用Java反射機(jī)制,通過class的名稱獲取Class對(duì)象 Class bean = Class.forName(cls.getText());
          //獲取對(duì)應(yīng)class的信息 java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean); //獲取其屬性描述 java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors(); //設(shè)置值的方法 Method mSet = null; //創(chuàng)建一個(gè)對(duì)象 Object obj = bean.newInstance();
          //遍歷該bean的property屬性 for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) { Element foo2 = (Element) ite.next(); //獲取該property的name屬性 Attribute name = foo2.attribute("name"); String value = null;
          //獲取該property的子元素value的值 for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) { Element node = (Element) ite1.next(); value = node.getText(); break; }
          for (int k = 0; k < pd.length; k++) { if (pd[k].getName().equalsIgnoreCase(name.getText())) { mSet = pd[k].getWriteMethod(); //利用Java的反射極致調(diào)用對(duì)象的某個(gè)set方法,并將值設(shè)置進(jìn)去 mSet.invoke(obj, value); } }                            } //將對(duì)象放入beanMap中,其中key為id值,value為對(duì)象 beanMap.put(id.getText(), obj); } } catch (Exception e) { System.out.println(e.toString()); }       } //other codes}

          最近給大家找了  通用權(quán)限系統(tǒng)


          資源,怎么領(lǐng)???


          掃二維碼,加我微信,回復(fù):通用權(quán)限系統(tǒng)

           注意,不要亂回復(fù) 

          沒錯(cuò),不是機(jī)器人
          記得一定要等待,等待才有好東西

          瀏覽 29
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩人妻一区二区三区 | 亚洲无码电影在线 | 伊人骚逼 | 美女骚逼丝袜野战视频 | 中文字幕日韩在线视频 |