An interesting thing for me, is that if I am active on twitter during daytime in India (now that I’m here on vacation), I get to have some interesting conversations about design and development. Today, I chanced to talk about the lack of unsigned values support in Java.
Java is, by no means, a “new” language for anyone I know. However, we still try to write C/C++ like code using it. We approach it with all of the training of C/C++, and start micro-optimisation much before it is needed, and end up with hard to comprehend complex code.
The reason for lack of unsigned types in Java are:
1. The core of the Java language was designed to be simple. This meant leaving out anything that adds complexity that can be done without. unsigned types didn’t make the cut
2. Someone got lazy and didn’t bother to implement them, when the time came to make Oak into Java. (I wish leaving things out like this happen more in the industry).
Now, let’s examine why one requires unsigned types:
1. Represent business case values like salary or percentile etc
2. Store bitsets – each bit representing some state or option
3. provide the ability to store more value that one can in an signed, thereby requiring lesser in-memory size
Case 1 is a no brainer: As long as the value fits within the bounds of a 32-bit integer, you shouldn’t care. Unless you need to store a value greater than 2,147,483,647, you shouldn’t care if it is signed or unsigned.
Case 2 is a hack: This is a typical carry-over from the C world, where there are no true enum or bitset types. If you need this, consider using an Enum or BitSet (as the case be for the problem you are trying to address)
Case 3 is a delusion, and a sin: To a certain extent this is also something that was necessary and a good thing in C, and almost useless, and sometimes wrong to do in Java. The cost and the risk of implementing a type, particularly one that will require, new arithmetic semantics to be written, is never justified. The less new language syntax one invents, the simpler the code is. My rule of thumb is – if I’m extending the language, I delete that class, and re-write it to use only existing semantics. If that means re-writing 5 other classes, so be it. In the long run, that yields a better, compact, and clean system.
Now contrast that, with using a signed int, where you expect the value to be unsigned. Unless you need to store a value greater than 2,147,483,647 there is no reason or benefit for implementing an unsigned int. Even in that case, unless you expect that to be marshalled to a system implemented in another language (like C/C++) via rpc, you should be using a long.
The next time you get the urge to extend the Java language, by defining a class that the language left out – think twice if you really need it. If, after deliberation, you still think you need it, implement it, use it in your code, delete the implementation and re-write your code. Trust me, it won’t have affected the application much, but your code will be cleaner and simpler to understand.
That is worth every extra-line of non-resuable code that you write.