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

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - Java 9中如何對IntegerCache進行修改詳解

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

2021-02-26 13:13Peter Verhas JAVA教程

這篇文章主要給大家介紹了關于Java 9中如何對IntegerCache進行修改的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或使用java9具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。

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

Java中Integer類的IntegerCache的作用

包名:java.lang

文件名:Integer.java

方法名:IntegerCache

方法的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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這個區間的對象的話,是直接使用這個Cache中的對象的。

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

引言

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

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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,然后使用隨機值對緩存進行填充(淘氣!)。

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

?
1
2
3
4
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 中是不會發生的。相當于說對象是不可范文的,因為 java.base 模塊的原因,這是 JDK 的組成部分,在每個 Java 程序啟動時被自動的導入,不允許打開未命名的模塊。這個異常是在當我們嘗試設置字段可訪問屬性時拋出的。

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

?
1
2
3
4
module myModule {
 exports com.javax0.module.demo;
 opens com.javax0.module.demo;
}

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

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

可行嗎?

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

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

總結

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎影视免费观看 | 欧美艳星kagney1ynn | 国产成人一区二区三区影院免费 | 美女1819xxxx| 欧美色精品天天在线观看视频 | 日本欧美强乱视频在线 | 亚洲第一网色综合久久 | 午夜国产精品影院在线观看 | 丝瓜视频在线观看污 | 青涩体验在线观看未删减 | 亚洲欧美国产精品完整版 | 久久综合亚洲色hezyo | 果冻传媒91| 亚洲另类中文字幕 | 欧美成人免费观看的 | 91亚洲在线| 免费尤物视频 | 万域之王动漫在线观看全集免费播放 | 亚洲AV精品一区二区三区不卡 | aⅴ导航站 | 国产黄频在线观看高清免费 | 午夜秀场在线观看 | 欧美a级v片在线观看一区 | uoco福利姬| 国产精品久久久天天影视香蕉 | 免费片在线观看高清 | 楚乔传第二部免费完整 | 色综合中文字幕天天在线 | www黄| 亚洲第五色综合网啪啪 | 91视频免费观看网站 | 加勒比成人 | 美女被的视频 | 亚洲天堂网站在线 | 久久久久999 | 欧美又大又粗又长又硬 | 免费黄色网站视频 | s8sp加密路线和免费路线首页 | 国产成人理在线观看视频 | 国产梦呦精品 | a国产在线 |