亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java 9中如何對IntegerCache進行修改詳解

 更新時間:2017年12月03日 10:28:35   作者:Peter Verhas  
這篇文章主要給大家介紹了關于Java 9中如何對IntegerCache進行修改的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或使用java9具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。

在開始本文的正文之前,我們下面來看看下面這段代碼:

Java中Integer類的IntegerCache的作用

包名:java.lang

文件名:Integer.java

方法名:IntegerCache

方法的代碼如下:

private static class IntegerCache { 
static final int high; 
static final Integer cache[]; 

static { 
final int low = -128; 

// high value may be configured by property 
int h = 127; 
if (integerCacheHighPropValue != null) { 
// Use Long.decode here to avoid invoking methods that 
// require Integer's autoboxing cache to be initialized 
int i = Long.decode(integerCacheHighPropValue).intValue(); 
i = Math.max(i, 127); 
// Maximum array size is Integer.MAX_VALUE 
h = Math.min(i, Integer.MAX_VALUE - -low); 
} 
high = h; 

cache = new Integer[(high - low) + 1]; 
int j = low; 
for(int k = 0; k < cache.length; k++) 
cache[k] = new Integer(j++); 
} 

private IntegerCache() {} 
} 

我們在代碼中看到,low為-128,high為127,這樣的話,在Java編程中,如果要使用-128——127這個區(qū)間的對象的話,是直接使用這個Cache中的對象的。

上面是段簡單的介紹,幫助大家理解下IntegerCache,下面開始本文的正文:

引言

5 年前,我在 Hungarian 上發(fā)表了一篇關于 JDK 中如何改變 IntegerCache 的文章。這種做法其實是深入進 Java 運行時,在實際并沒有使用的場景。當你開發(fā)這些研究代碼時,你才能更好的理解反射是如何工作的,以及 Integer 類是如何實現(xiàn)的。

Integer 類有一個私有的嵌套內,名為 IntegerCache ,包含了值從 -127 到 128 的 Integer 對象。

當代碼需要從 int 類型封箱成 Integer 對象,而且值在這個范圍內時,那么 Java 運行時會使用這個緩存,而不是創(chuàng)建一個新的 Integer 對象。這主要是處于性能優(yōu)化的考慮,我們必須牢記在心的是很多 int 值在程序中很多時候都處于這個范圍內(例如數(shù)組的下標索引)。

這樣做的副作用是,很多時候,使用等號操作符來比較兩個 Integer 對象時,只要值在范圍內都是有效的。這在單元測試中很典型。而在運行模式下,當數(shù)值大于 128 時,代碼執(zhí)行會失敗。

使用反射來訪問 IntegerCache 類時會導致一些奇怪的副作用,注意這會影響到整個的 JVM。如果一個 Servlet 重新定義了小的 Integer 緩存值,那么所有運行在同一個 Tomcat 下的其他 Servlet 也遭遇同樣問題。

Lukas EderSitepoint 上面還有其他一些文章描述此問題。

現(xiàn)在我已經(jīng)開始在玩弄 Java 9 的早期發(fā)布版本,在我腦海里我一直要做的就是對新的 Java 版本進行各種實驗。在開始之前,讓我們先看看在 Java 8 中的做法。

在 Lukas 的文章中,我將他的示例代碼貼在此處:

import java.lang.reflect.Field;
import java.util.Random;

public class Entropy {
 public static void main(String[] args)
 throws Exception {

 // Extract the IntegerCache through reflection
 Class << ? > clazz = Class.forName(
  "java.lang.Integer$IntegerCache");
 Field field = clazz.getDeclaredField("cache");
 field.setAccessible(true);
 Integer[] cache = (Integer[]) field.get(clazz);

 // Rewrite the Integer cache
 for (int i = 0; i < cache.length; i++) {
  cache[i] = new Integer(
  new Random().nextInt(cache.length));
 }

 // Prove randomness
 for (int i = 0; i < 10; i++) {
  System.out.println((Integer) i);
 }
 }
}

此代碼通過反射方式訪問 IntegerCache,然后使用隨機值對緩存進行填充(淘氣?。?/p>

我們嘗試在 Java 9 中執(zhí)行相同的代碼,別指望有什么樂趣。當有人嘗試違反它時會發(fā)現(xiàn) Java 9 的限制更加嚴格。

Exception in thread "main" java.lang.reflect.InaccessibleObjectException:
 Unable to make field static final java.lang.Integer[]
 java.lang.Integer$IntegerCache.cache
 accessible: module java.base does not "opens java.lang" to unnamed module @1bc6a36e

程序拋出了異常,這個異常在 Java 8 中是不會發(fā)生的。相當于說對象是不可范文的,因為 java.base 模塊的原因,這是 JDK 的組成部分,在每個 Java 程序啟動時被自動的導入,不允許打開未命名的模塊。這個異常是在當我們嘗試設置字段可訪問屬性時拋出的。

我們在 Java 8 可輕松訪問的對象,現(xiàn)在在 Java 9 中不能訪問了,因為新的模塊系統(tǒng)對此進行了保護。代碼只能訪問字段、方法和其他用反射能訪問的信息,只有當類在相同的模塊中,或者模塊打開了包用于反射方式訪問。這個可以通過  module-info.java 模塊定義文件來實現(xiàn):

module myModule {
 exports com.javax0.module.demo;
 opens com.javax0.module.demo;
}

這個模塊 java.base 不用不用自行打開用于反射訪問,特別是未命名模塊更不需要。如果我們創(chuàng)建了一個模塊并進行命名,那么錯誤信息將包含模塊的名稱。

我們能否在程序里打開模塊呢? java.lang.reflect.Module 模塊有一個 addOpens 的方法可以做到。

可行嗎?

對開發(fā)者來說壞消息是:不可行。它只能在另外一個模塊中打開一個模塊中的包,并且包已經(jīng)在該模塊中通過調用這個方法打開過。這種方法只能讓模塊傳遞給另外的模塊權利,前提是另外的模塊已經(jīng)以某種方式打開過相同的包,而不能打開沒有打開過的包(譯者注:很難理解,不是嗎?)。

但與此同時好消息是:Java 9 不像 Java 8 那么容易被破解。最少這個漏洞被關閉了??雌饋?Java 開始往專業(yè)級發(fā)展,而不僅僅是個玩具(譯者注:誰說 Java 是個玩具了?)。不久的將來你可以非常嚴肅的將 RPG 和 COBOL 語言的項目遷移到 Java 上了。(很抱歉,我開玩笑的)

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

本文翻譯自:https://dzone.com/articles/hacking-the-integercache-in-java-9

相關文章

  • Linux下Hadoop?2.7.3?安裝搭建過程

    Linux下Hadoop?2.7.3?安裝搭建過程

    Hadoop實現(xiàn)了一個分布式文件系統(tǒng)(Hadoop?Distributed?File?System),簡稱HDFS,這篇文章給大家介紹Linux下Hadoop?2.7.3?安裝搭建過程,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • SpringBoot+阿里云OSS實現(xiàn)在線視頻播放的示例

    SpringBoot+阿里云OSS實現(xiàn)在線視頻播放的示例

    這篇文章主要介紹了SpringBoot+阿里云OSS實現(xiàn)在線視頻播放的示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 從字符串中截取等長字節(jié)的Java代碼

    從字符串中截取等長字節(jié)的Java代碼

    這篇文章主要介紹了從字符串中截取等長字節(jié)的Java代碼,有需要的朋友可以參考一下
    2013-12-12
  • 通過使用Byte?Buddy便捷創(chuàng)建Java?Agent

    通過使用Byte?Buddy便捷創(chuàng)建Java?Agent

    這篇文章主要為大家介紹了如何通過使用Byte?Buddy便捷創(chuàng)建Java?Agent的使用說明,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • java根據(jù)ip地址獲取詳細地域信息的方法

    java根據(jù)ip地址獲取詳細地域信息的方法

    這篇文章主要介紹了java根據(jù)ip地址獲取詳細地域信息的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 詳解Java中的內存屏障

    詳解Java中的內存屏障

    這篇文章主要介紹了Java中的內存屏障的相關資料,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-05-05
  • springboot框架各個層次基礎詳解

    springboot框架各個層次基礎詳解

    這篇文章主要介紹了springboot框架各個層次基礎,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用spring stream發(fā)送消息代碼實例

    使用spring stream發(fā)送消息代碼實例

    這篇文章主要介紹了使用spring stream發(fā)送消息代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java如何獲取對象屬性及對應值

    Java如何獲取對象屬性及對應值

    這篇文章主要介紹了Java如何獲取對象屬性及對應值,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • 使用MyBatis返回其它類對象的字段處理

    使用MyBatis返回其它類對象的字段處理

    這篇文章主要介紹了使用MyBatis返回其它類對象的字段處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論