“cv”:
Isso foi feito explicitamente no design da linguagem. Em C ou C++, sempre dava algum pepino converter um unsigned int pra int, e vice-versa. Alem do que, se vc quer especificar uma invariante, especifique no código! Imagine como seria ter um tipo específico para a invariante mais famosa de todas, Object o != null:
notnull Object o = new Object();
Object p = null;
o = p; // erro de compilacao? de runtime? nem da erro?
Os problemas do c/c++ são advendos do fato de ser uma linguagêm fracamente tipada, converter qualquer coisa pra qualquer coisa é válido e, algumas vezes, necessario.
Em Java poderia fazer que conversão entre tipos com/sem sinal exigir um cast sempre que fosse de estreitamento. Ex: unsigned int -> int.
Cv, existem algumas linguagens que possuem marcação para quando uma variavel não pode ser nula e funciona muito bem. No seu exemplo, não compilaria e colocando o devido cast, um NullPointerException seria lançado.
Existe o mito que expressar invariantes na linguagem é uma coisa ruim, que não escalam com o crecimento do código. Bom java possui, poucas pessoas reclamam o Carlos Perez é um, checked exceptions.
Agora me diga sinceramente, olhando grande parte do seu código, em quantos lugares você lida com checked exceptions não por que você queria mais porque foi obrigado? Quantos try/catch e throws você escreveu somente para satisfazer elas? Agora não sou eu que vou dizer que checked exceptions são ruins.
Suporte da linguagem a invariantes obriga o programador a deixar de ser folgado e seguir elas por toda aplicação.
Mas isso ta fugindo um pouco do escopo dessa discução. Não acho que ter ou não tipos sem sinal se restringe ao argumento que acabei de dissertar sobre.