|
The Java Specialists' Newsletter
Issue 102 2005-01-31
Category:
Language
Java version: Sun JDK 1.5.0_01 Mangling Integersby 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.
Thanks for reading this newsletter on our website. We also have a mailing list. That is where the real action takes place (webinars, free reports, etc.). Maybe subscribe today?
Advanced Java Courses on Crete:Java Specialists Master Course 18-21 June 2013 and
Concurrency Specialists Course 6-9 August 2013.
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
Discuss at The Java Specialist Club
|