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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # `sun.misc.Unsafe`類的用法 > 原文: [https://howtodoinjava.com/java/basics/usage-of-class-sun-misc-unsafe/](https://howtodoinjava.com/java/basics/usage-of-class-sun-misc-unsafe/) 這篇文章是有關 [**Java**](//howtodoinjava.com/tag/java-hidden-features/ "java hidden features") 鮮為人知的特性的討論順序的下一個更新。 請**通過電子郵件**訂閱,以在下一次討論進行時進行更新。 并且不要忘記在評論部分表達您的觀點。 Java 是一種安全的編程語言,可以防止程序員犯很多愚蠢的錯誤,這些錯誤大多數是基于內存管理的。 但是,如果您決定將其弄亂,則可以使用`Unsafe`類。 此類是`sun.*`API,其中**并不是 J2SE** 的真正組成部分,因此您可能找不到任何正式文檔。 可悲的是,它也沒有任何好的代碼文檔。 ## `sun.misc.Unsafe`的實例化 如果嘗試創建`Unsafe`類的實例,則由于兩個原因,將不允許您這樣做。 1)不安全類具有私有構造器。 2)它也具有靜態的`getUnsafe()`方法,但是如果您樸素地嘗試調用`Unsafe.getUnsafe()`,則可能會得到`SecurityException`。 此類只能從受信任的代碼實例化。 但是總有一些解決方法。 創建實例的類似的簡單方法是使用反射: ```java Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference f.setAccessible(true); Unsafe unsafe = (Unsafe) f.get(null); ``` 注意:您的 IDE,例如 eclipse 可能顯示與訪問限制有關的錯誤。 不用擔心,繼續運行程序。 它將運行。 現在到主要部分。 使用此對象,您可以執行“有趣的”任務。 ## `sun.misc.Unsafe`的使用 **1)創建不受限制的實例** 使用`allocateInstance()`方法,您可以創建類的實例,而無需調用其構造器代碼,初始化代碼,各種 JVM 安全檢查以及所有其他低級內容。 即使類具有私有構造器,也可以使用此方法創建新實例。 所有單例愛好者的噩夢。 伙計們,您只是無法輕松應對這種威脅。 舉個例子: ```java public class UnsafeDemo { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException { Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference f.setAccessible(true); Unsafe unsafe = (Unsafe) f.get(null); //This creates an instance of player class without any initialization Player p = (Player) unsafe.allocateInstance(Player.class); System.out.println(p.getAge()); //Print 0 p.setAge(45); //Let's now set age 45 to un-initialized object System.out.println(p.getAge()); //Print 45 System.out.println(new Player().getAge()); //This the normal way to get fully initialized object; Prints 50 } } class Player{ private int age = 12; public Player(){ //Even if you create this constructor private; //You can initialize using Unsafe.allocateInstance() this.age = 50; } public int getAge(){ return this.age; } public void setAge(int age){ this.age = age; } } Output: 0 45 50 ``` **2)使用直接內存訪問的淺克隆** 通常如何進行淺克隆? 在`clone(){..}`方法中調用`super.clone()`吧? 這里的問題是,您必須實現`Cloneable`接口,然后在要實現淺層克隆的所有類中覆蓋`clone()`方法。 懶惰的開發人員要付出太多努力。 我不建議這樣做,但是使用不安全的方法,我們可以在幾行中創建淺表克隆,最好的部分是它可以與任何類一起使用,就像某些工具方法一樣。 訣竅是將對象的字節復制到內存中的另一個位置,然后將該對象類型轉換為克隆的對象類型。 **3)黑客的密碼安全性** 這看起來很有趣嗎? 是的,是的。 開發人員創建密碼或將密碼存儲在字符串中,然后在應用程序代碼中使用它們。 使用密碼后,更聰明的開發人員將字符串引用設置為`NULL`,以便不再對其進行引用,并且可以輕松地對其進行垃圾回收。 但是從那時起,您對垃圾回收器啟動時的引用為`null`,該字符串實例位于字符串池中。 對您的系統進行的復雜攻擊將能夠讀取您的內存區域,從而也可以訪問密碼。 機會很低,但他們在這里。 因此,建議使用`char []`存儲密碼,以便在使用后可以遍歷數組并使每個字符變臟/變空。 另一種方法是使用我們的魔術類“不安全”。 在這里,您將創建另一個長度與密碼相同的臨時字符串,并存儲“`?`”或為臨時密碼中的每個字符輸入“`*`”(或任何字母)。 完成密碼邏輯操作后,您只需將臨時密碼(例如`????????`)的字節復制到原始密碼上即可。 這意味著用臨時密碼覆蓋原始密碼。 示例代碼如下所示。 ```java String password = new String("l00k@myHor$e"); String fake = new String(password.replaceAll(".", "?")); System.out.println(password); // l00k@myHor$e System.out.println(fake); // ???????????? getUnsafe().copyMemory(fake, 0L, null, toAddress(password), sizeOf(password)); System.out.println(password); // ???????????? System.out.println(fake); // ???????????? ``` 在運行時動態創建類 我們可以在運行時創建類,例如從已編譯的`.class`文件中。 要將讀取的類內容執行到字節數組,然后將其傳遞給`defineClass`方法。 ```java //Sample code to craeet classes byte[] classContents = getClassContent(); Class c = getUnsafe().defineClass(null, classContents, 0, classContents.length); c.getMethod("a").invoke(c.newInstance(), null); //Method to read .class file private static byte[] getClassContent() throws Exception { File f = new File("/home/mishadoff/tmp/A.class"); FileInputStream input = new FileInputStream(f); byte[] content = new byte[(int)f.length()]; input.read(content); input.close(); return content; } ``` **4)超大數組** 如您所知,`Integer.MAX_VALUE`常量是 java 數組的最大大小。 如果要構建真正的大數組(盡管在常規應用程序中沒有實際需要),則可以為此使用直接內存分配。 以此類的示例為例,該類創建的順序存儲器(數組)的大小是允許的大小的兩倍。 ```java class SuperArray { private final static int BYTE = 1; private long size; private long address; public SuperArray(long size) { this.size = size; address = getUnsafe().allocateMemory(size * BYTE); } public void set(long i, byte value) { getUnsafe().putByte(address + i * BYTE, value); } public int get(long idx) { return getUnsafe().getByte(address + idx * BYTE); } public long size() { return size; } } ``` 用法示例: ```java long SUPER_SIZE = (long)Integer.MAX_VALUE * 2; SuperArray array = new SuperArray(SUPER_SIZE); System.out.println("Array size:" + array.size()); // 4294967294 for (int i = 0; i < 100; i++) { array.set((long)Integer.MAX_VALUE + i, (byte)3); sum += array.get((long)Integer.MAX_VALUE + i); } System.out.println("Sum of 100 elements:" + sum); // 300 ``` 請注意,這會導致 JVM 崩潰。 ## 總結 `sun.misc.Unsafe`提供了幾乎無限的能力來探索和修改 VM 的運行時數據結構。 盡管事實上這些特性幾乎不能在 Java 開發本身中使用,但是對于希望在不進行 C++代碼調試的情況下研究 HotSpot VM 或需要創建臨時分析工具的任何人來說,`Unsafe`都是一個不錯的工具。 **參考:** <http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/> **祝您學習愉快!**
                  <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>

                              哎呀哎呀视频在线观看