The lack of unsigned integers as primitives in Java was a significant (and unnecessary) defect in the design of the language. I am glad they are finally starting to address it.
There are a number of codes and algorithms that are difficult to implement without unsigned integer primitives. You can make the algorithms work with the signed primitives but the implementation is nowhere near as fast or elegant as what you can do in a language like C or C++. There are many use cases for data types that behave like pure bit strings with no concept of sign.
That's one thing about Java I never agreed with. I can understand the idea that most of the time you don't really need unsigned types, but I think having the extra checking would be nice.
The place where it's a real problem is when you have to do any low level stuff. You read in bytes and they're all signed. So you either have to adjust them all (such as promoting them to shorts), so change the algorithm to handle the signs (which may make it quite a bit harder to read).
If you had to do enough, it would probably just be easier to do that stuff with JNI, but that's quite a bit less portable and something of a hassle.
Arithmetic aside, the byte-code is set in stone. It's even interpreted on silicon now on ARM processors with jazella. It's going to be an incredibly difficult effort to ever add unsigned types truly to Java without it effectively becoming a hard fork.
Hardly anyone ever used Jazelle. I'm sure someone did but I don't know of a single production system using it today (maybe some legacy java based mobiles).
Jazelle does not execute bytecode directly, it is not a JVM. It is a small subset of the features needed and to use it at all required a JVM written specifically for it along with specific OS support. It also required a specific licence from ARM to use.
Ultimately, JIT based JVMs performed as well or better than Jazelle without the implementation specific development time or licencing costs of Jazelle.
For all intents and purposes, Jazelle was a complete failure.
The bytecode isn't set in stone at all. Java 7 added InvokeDynamic, to name one bytecode.
Jazelle is basically being phased out in favor of the much-more-generic ThumbEE, which isn't onerously licensed and entirely undocumented and hence has a chance of actually being used. New ARM CPUs "support" Jazelle by effectively ignoring it.
It'd of course take a major-version Java release to add unsigned type bytecodes if they chose to go that route (rather than the current approach, which seems to be providing a dangerous and half-baked set of methods on Integer instead). But it certainly isn't impossible by any means.
Interestingly, you don't need to add a "full set" of bytecodes for unsigned arithmetic support - just four (udiv, ludiv, urem, lurem). All the other arithmetic operations are bit-identical with the existing signed versions.
It's also worth noting that existing Jazelle implementations don't do everything in hardware, they already call into a software piece to handle any opcodes they come across that they don't interpret natively. So improving those to handle new opcodes is just a software upgrade, same as anything else.
The biggest issue with adding those op code is the lack of space for every op code to support between every type IIRC. every new type exponentially increases the number of operations. Being that we can only 255 op code in Java, it causes a bit of a problem. In CIL/MSIL in .NET, they used a multibyte technique with flag bits IIRC. (Don't quote me but I'm recalling designs I seen 8 years ago here).
If you are using integers as, well, integers then there is relatively little benefit other than compatibility with data structures from other languages (e.g. wire protocols). However, unsigned integers are also the building blocks of large bit string structures i.e. bit structures that are not interpreted as integers per se. For these it is a bigger problem. It is not the range issue so much as you have a bit that behaves differently than the others e.g. for operations like comparisons.
For kernels that do a lot of manipulation on largish bit strings there are two ways you can deal with it: use some additional conditional logic that treats the sign bit as special or design your code so that it can accept "gaps" in the bit string.
The reason you might want to do direct unsigned 64-bit bit-twiddling on packed bit string structures is blinding speed. It fully utilizes your CPU's ALUs. The equivalent code when limited to signed integers injects branches, extra operations, and/or requires working in 32-bit chunks, all of which slow down the code significantly and makes it uglier to boot.
For most apps it doesn't matter. For some algorithms that work on large bit strings it makes implementation in Java more painful than it needs to be.
There are a number of codes and algorithms that are difficult to implement without unsigned integer primitives. You can make the algorithms work with the signed primitives but the implementation is nowhere near as fast or elegant as what you can do in a language like C or C++. There are many use cases for data types that behave like pure bit strings with no concept of sign.