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

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.

Upcoming Java Specialist Master Courses: - please click here to sign up.

As from May 2010, we are also offering this course on the island of Crete. We only accept 6 students per class in Crete, due to the size of our conference room. Please book early to avoid disappointment!

San Jose CA, Mar 16-19 2010, $3500
Ottawa, Canada, Mar 22-25 2010, $3500
Oslo, Norway, Apr 13-16 2010, Kr 24500
Montreal, Canada, Apr 20-23 2010, $3500
Toronto, Canada, May 17-20 2010, $3500
Chania, Crete, May 25-28, Jun 29-Jul 2 or Aug 24-27 2010, €2500

In-house courses if these dates or locations do not suit you - click here for more information.

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 AddThis Social Bookmark Button

Book Review
Concurrency
Exceptions
GUI
Inspirational
Language
Performance
Software Engineering
Tips and Tricks
© 2009 Heinz Kabutz - All Rights Reserved Sitemap seo web design Catch22 Marketing