Why doesn't Java support unsigned ints?
Why doesn't Java include support for unsigned integers?
It seems to me to be an odd omission, given that they allow one to write code that is less likely to produce overflows on unexpectedly large input.
Furthermore, using unsigned integers can be a form of self-documentation, since they indicate that the value which the unsigned int was intended to hold is never supposed to be negative.
Lastly, in some cases, unsigned integers can be more efficient for certain operations, such as division.
What's the downside to including these?
This is from an interview with Gosling and others, about simplicity:
Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up.
Reading between the lines, I think the logic was something like this:
Mostly, I'd say it was a reasonable decision. Possibly, I would have:
Still, with a bit of kludging, operations on unsigned values up to 32 bits aren't tooo bad, and most people don't need unsigned 64-bit division or comparison.
This is an older question and pat did briefly mention char, I just thought I should expand upon this for others who will look at this down the road. Let's take a closer look at the Java primitive types:
byte
- 8-bit signed integer
short
- 16-bit signed integer
int
- 32-bit signed integer
long
- 64-bit signed integer
char
- 16-bit character (unsigned integer)
Although char
does not support unsigned
arithmetic, it essentially can be treated as an unsigned
integer. You would have to explicitly cast arithmetic operations back into char
, but it does provide you with a way to specify unsigned
numbers.
char a = 0;
char b = 6;
a += 1;
a = (char) (a * b);
a = (char) (a + b);
a = (char) (a - 16);
b = (char) (b % 3);
b = (char) (b / a);
//a = -1; // Generates complier error, must be cast to char
System.out.println(a); // Prints ?
System.out.println((int) a); // Prints 65532
System.out.println((short) a); // Prints -4
short c = -4;
System.out.println((int) c); // Prints -4, notice the difference with char
a *= 2;
a -= 6;
a /= 3;
a %= 7;
a++;
a--;
Yes, there isn't direct support for unsigned integers (obviously, I wouldn't have to cast most of my operations back into char if there was direct support). However, there certainly exists an unsigned primitive data type. I would liked to have seen an unsigned byte as well, but I guess doubling the memory cost and instead use char is a viable option.
Edit
With JDK8 there are new APIs for Long
and Integer
which provide helper methods when treating long
and int
values as unsigned values.
compareUnsigned
divideUnsigned
parseUnsignedInt
parseUnsignedLong
remainderUnsigned
toUnsignedLong
toUnsignedString
Additionally, Guava provides a number of helper methods to do similar things for at the integer types which helps close the gap left by the lack of native support for unsigned
integers.
上一篇: Java 7中的钻石操作符有什么意义?