<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 反射機制概念 JAVA反射機制是在運行狀態中,對于任意一個實體類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。 主要是指程序可以訪問,檢測和修改它本身狀態或行為的一種能力,并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。在java中,只要給定類的名字,那么就可以通過反射機制來獲得類的所有信息。 反射是Java中一種強大的工具,能夠使我們很方便的創建靈活的代碼,這些代碼可以再運行時裝配,無需在組件之間進行源代碼鏈接。但是反射使用不當會成本很高! 類中有什么信息,利用反射機制就能可以獲得什么信息,不過前提是得知道類的名字。所有類的對象其實都是Class的實例。 ## 反射機制的作用 - 在運行時判斷任意一個對象所屬的類; - 在運行時構造任意一個類的對象; - 在運行時判斷任意一個類所具有的成員變量和方法; - 在運行時調用任意一個對象的方法; - 生成動態代理。 ## 反射機制的優點與缺點 首先要搞清楚為什么要用反射機制?直接創建對象不就可以了嗎,這就涉及到了動態與靜態的概念。 - 靜態編譯:在編譯時確定類型,綁定對象,即通過。 - 動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多態的應用,有以降低類之間的藕合性。 #### 反射機制的優點 可以實現動態創建對象和編譯,體現出很大的靈活性(特別是在J2EE的開發中它的靈活性就表現的十分明顯)。通過反射機制我們可以獲得類的各種內容,進行了反編譯。對于JAVA這種先編譯再運行的語言來說,反射機制可以使代碼更加靈活,更加容易實現面向對象。   比如,一個大型的軟件,不可能一次就把把它設計的很完美,當這個程序編譯后,發布了,當發現需要更新某些功能時,我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個軟件肯定是沒有多少人用的。采用靜態的話,需要把整個程序重新編譯一次才可以實現功能的更新,而采用反射機制的話,它就可以不用卸載,只需要在運行時才動態的創建和編譯,就可以實現該功能。 #### 反射機制的缺點 對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它 滿足我們的要求。這類操作總是慢于只直接執行相同的操作。 ## 反射機制的示例 ```java import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; class Car { private String brand; private String color; private int maxSpeed; public Car() { } public Car(String brand, String color, int maxSpeed) { this.brand = brand; this.color = color; this.maxSpeed = maxSpeed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } public void introduce() { System.out.println("brand:" + brand + "; color:" + color + "; maxspeed:" + maxSpeed); } } public class hello { public static void main(String[] args) { // 通過類加載器加載Car類對象 ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class<?> clazz = null; try { clazz = loader.loadClass("Car"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 獲取類的默認構造器并通過它實例化Car Constructor<?> cons = null; Car car = null; try { cons = clazz.getDeclaredConstructor((Class[]) null); car = (Car) cons.newInstance(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } // 通過反射方法設置屬性 Method setBrand = null; try { setBrand = clazz.getMethod("setBrand", String.class); setBrand.invoke(car, "紅旗CA72"); Method setColor = clazz.getMethod("setColor", String.class); setColor.invoke(car, "黑色"); Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class); setMaxSpeed.invoke(car, 200); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } ``` ## 類的生命周期 ![](http://47.107.171.232/easily-j/images/20190110/3c5b5965-e944-4054-b5c1-3aab527f9c61.png) #### 加載 我們編寫一個java的源文件,經過編譯后生成一個后綴名為.class的文件,這結合四字節碼文件,java虛擬機就識別這種文件,java的生命周期就是class文件從加載到消亡的過程。 關于加載,其實,就是將源文件的class文件找到類的信息將其加載到方法區中,然后在堆區中實例化一個java.lang.Class對象,作為方法區中這個類的信息的入口。但是這一功能是在JVM之外實現的,主要的原因是方便讓應用程序自己決定如何獲取這個類,在不同的虛擬機實現的方式不一定相同,hotspot虛擬機是采用需要時在加載的方式,也有其他是先預先加載的。 #### 連接 一般會跟加載階段和初始化階段交叉進行,過程由三部分組成:驗證、準備和解析三步: - 驗證:確定該類是否符合java語言的規范,有沒有屬性和行為的重復,繼承是否合理,總之,就是保證jvm能夠執行 - 準備:主要做的就是為由static修飾的成員變量分配內存,并設置默認的初始值 默認初始值如下: 1. 八種基本數據類型默認的初始值是0 2. 引用類型默認的初始值是null 3. 有static final修飾的會直接賦值,例如:static final int x=10;則默認就是10. - 解析:這一階段的任務就是把常量池中的符號引用轉換為直接引用,說白了就是jvm會將所有的類或接口名、字段名、方法名轉換為具體的內存地址。 #### 初始化 這個階段就是將靜態變量(類變量)賦值的過程,即只有static修飾的才能被初始化,執行的順序就是: 父類靜態域或著靜態代碼塊,然后是子類靜態域或者子類靜態代碼塊 #### 使用 在類的使用過程中依然存在三步:對象實例化、垃圾收集、對象終結: - 對象實例化 就是執行類中構造函數的內容,如果該類存在父類JVM會通過顯示或者隱示的方式先執行父類的構造函數,在堆內存中為父類的實例變量開辟空間,并賦予默認的初始值,然后在根據構造函數的代碼內容將真正的值賦予實例變量本身,然后,引用變量獲取對象的首地址,通過操作對象來調用實例變量和方法 - 垃圾收集 當對象不再被引用的時候,就會被虛擬機標上特別的垃圾記號,在堆中等待GC回收 - 對象的終結 對象被GC回收后,對象就不再存在,對象的生命也就走到了盡頭 #### 類卸載 即類的生命周期走到了最后一步,程序中不再有該類的引用,該類也就會被JVM執行垃圾回收,從此生命結束…
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看