Java Specialists' Java Training Europehome of the java specialists' newsletter

The Java Specialists' Newsletter
Issue 1022005-01-31 Category: Language Java version: Sun JDK 1.5.0_01

GitHub Subscribe Free RSS Feed

Mangling Integers

by Dr. Heinz M. Kabutz

Welcome to the 102nd edition of The Java(tm) Specialists' Newsletter. I am in Johannesburg this week, presenting my first Java 5 Delta Course - Letting the Tiger out of the cage. This course is for professional Java programmers, who have already managed the nuances of JDK 1.4. Java Tiger has many pitfalls, and the syntax is at times, well, strange. Today we learned what this means:

    public static <T extends Comparable<? super T>> void sort(List<T> list)
  

A few words about Johannesburg. It is a young city, and bustling with activity. I arrived much too early this morning since the chauffeur service overestimated the traffic, and even at 6:30am, my customer's building was a hive of activity. It is also a dangerous place to be, so the chauffeur is not a luxury. For example, you should not walk down the road carrying a notebook, a wallet or even a mobile phone. You could be relieved of your burdens! On the positive side, the people here are very friendly and welcoming.

NEW: Please see our new "Extreme Java" course, combining concurrency, a little bit of performance and Java 8. Extreme Java - Concurrency & Performance for Java 8.

Mangling Integers

When I was a kid, I enjoyed fiddling with computers, so my aunt Elke gave me a sign that read: "To err is human, to really louse things up requires a computer."

I believe that Java misses a feature, that would make it a lot safer. It should be possible to make the contents of arrays immutable. A final handle does not help at all, since the elements of the array can still be changed.

In Issue 14, I gave an example of how it was possible to have ("hi there".equals("cheers !")) == true. This could easily have been made impossible by adding a language feature to prevent users from modifying the contents of an array.

However, this gets much worse with auto-boxing. Integer, Long, Short and Byte have now got a new function called Integer valueOf(int). This follows the Flyweight Pattern, similar to String objects, but only caches Integer objects from -128 to 127, inclusive. It either returns an Integer object from the cache, or creates a new object.

Nice function this valueOf(int), but I wondered what would happen if that cache were to get corrupted? The interesting part about this function is that it is called by all the autoboxing code generated by the compiler. So if it returned incorrect values, the entire number system of Java would be corrupted ... for example ...

public class Arithmetic {
  public static void main(String[] args) {
    CoolClass.makeExcellentCuppaCoffee(); // hmmm - we all need that!
    int upto = 1000;

    // using Integer
    Integer total1 = 0;
    for(int i=1; i<=upto; i++) {
      total1 += i;
    }
    System.out.println("total1 = " + total1);

    // using int
    int total2 = 0;
    for(int i=1; i<=upto; i++) {
      total2 += i;
    }
    System.out.println("total2 = " + total2);

    System.out.println("Should be " + ((upto+1)*upto)/2);
  }
}
  

The output on my machine is:

  Hmmm, the first cuppa in the morning is the best!
  total1 = 492372
  total2 = 500500
  Should be 500500
  

I have not shown you the fantastic coffee-making method in the CoolClass. Here goes:

import java.lang.reflect.Field;

public class CoolClass {
  static {
    try {
      Class[] classes = Integer.class.getDeclaredClasses();
      for (Class clazz : classes) {
        if (clazz.getName().endsWith("IntegerCache")) {
          Field cacheField = clazz.getDeclaredField("cache");
          cacheField.setAccessible(true);
          Integer[] cache = (Integer[]) cacheField.get(null);
          for (int i = 0; i < cache.length; i++) {
            cache[i] = new Integer(0);
          }
        }
      }
    } catch (Throwable e) {
      // we silently pretend we didn't want to destroy Java...
    }
  }

  public static void makeExcellentCuppaCoffee() {
    // let's pretend this function does something amazing,
    // like make a good cup of coffee
    System.out.println("Hmmm, the first cuppa in the morning is the best!");
  }
}
  

Of course, this is not Java's fault, but of lax security procedures. First off, you should always run your programs with a security manager, even if you do not think you need it. And of course, any libraries that you use should be checked for malicious code.

It is a pity though that you cannot turn autoboxing off, and that you are not able to easily find all places that use autoboxing, just to know what code to verify. Who knows, maybe in future we will have a -Xlint option to show us where autoboxing is used.

Kind regards

Heinz

Language Articles Related Java Course

Java Master
Java Concurrency
Design Patterns
In-House Courses



© 2010-2014 Heinz Kabutz - All Rights Reserved Sitemap
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. JavaSpecialists.eu is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.
@CORE_THE_BAND #RBBJGR