How to modify IntegerCache in Java 9

Source: Internet
Author: User

How to modify IntegerCache in Java 9

Before starting the text of this article, let's take a look at the following code:

Functions of Integer class IntegerCache in Java

Package name: java. lang

File Name: Integer. java

Method Name: IntegerCache

The method code is as follows:

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() {} } 

In the code, we can see that low is-128 and high is 127. In this case, in Java programming, if you want to use objects in the range-128--127, directly use the objects in the Cache.

The above section is a simple introduction to help you understand IntegerCache. The body of this article is as follows:

Introduction

Five years ago, I published an article on how JDK changed IntegerCache on Hungarian. This is actually a scenario that is not actually used in Java runtime. When developing these research codes, you can better understand how reflection works and how Integer classes are implemented.

The Integer class contains a private nested Integer object named IntegerCache, which contains values from-127 to 128.

When the code needs to be encapsulated from the int type into an Integer object and the value is within this range, the Java runtime will use this cache instead of creating a new Integer object. This is mainly in consideration of performance optimization. We must keep in mind that many int values are in this range in the Program (for example, the subscript index of an array ).

The side effect of this operation is that when the equal sign operator is used to compare two Integer objects, the value is valid within the range. This is typical in unit testing. In running mode, code execution fails when the value is greater than 128.

Using Reflection to access the IntegerCache class may cause some strange side effects. Note that this will affect the entire JVM. If a Servlet re-defines a small Integer cache value, all other Servlets running under the same Tomcat will encounter the same problem.

There are other articles describing this issue in Lukas Eder and Sitepoint.

Now I have started to play with the early release of Java 9. In my mind, all I have to do is to experiment with the new Java version. Before starting, let's take a look at the practices in Java 8.

In Lukas's article, I pasted his sample code here:

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); } }}

This code accesses IntegerCache through reflection, and then fills the cache with random values (naughty !).

We try to execute the same code in Java 9 and don't expect any fun. When someone tries to violate it, it will find that Java 9 is more restrictive.

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

The program throws an exception, which will not occur in Java 8. It is equivalent to saying that the object is not an example. Because of the java. base module, this is a part of JDK. It is automatically imported when each Java program is started, and untitled modules cannot be opened. This exception is thrown when we try to set the field accessible attribute.

Objects that can be easily accessed in Java 8 cannot be accessed in Java 9, because the new module system protects them. The code can only access fields, methods, and other information that can be accessed by reflection. Only when the class is in the same module, or the module opens the package for reflection access. This can be achieved through the module-info.java module definition file:

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

This java. base module does not need to be opened for reflection access, especially for untitled modules. If a module is created and named, the error message contains the module name.

Can we open the module in the program?java.lang.reflect.Module The module has an addOpens method.

Is it feasible?

Bad news for developers is: not feasible. It can only open packages in one module in another module, and the package has been opened in this module by calling this method. This method can only pass the module to another module, provided that the other module has opened the same package in some way, but cannot open the unopened package: it's hard to understand, isn't it ?).

But at the same time, the good news is that Java 9 is not as easy to crack as Java 8. At least this vulnerability is disabled. It seems that Java has started to develop at the Professional level, not just a toy (Note: Who said Java is a toy ?). In the near future, you will be very serious about migrating RPG and COBOL projects to Java. (Sorry, I'm kidding)

Summary

The above is all the content of this article. I hope the content of this article has some reference and learning value for everyone's learning or work. If you have any questions, please leave a message to us, thank you for your support.

Https://dzone.com/articles/hacking-the-integercache-in-java-9

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.