Ответ
Да, все целочисленные примитивные типы в Java (byte, short, int, long) являются знаковыми (signed). Они используют старший бит для знака и могут представлять как положительные, так и отрицательные числа.
Диапазоны знаковых типов:
byte: от -128 до 127short: от -32 768 до 32 767int: от -2³¹ до 2³¹-1long: от -2⁶³ до 2⁶³-1
Работа с беззнаковой (unsigned) интерпретацией:
Начиная с Java 8, в классах-обертках (Integer, Long) появились статические методы для обработки значений в беззнаковом контексте.
// Знаковое хранение
int signed = -42;
System.out.println(signed); // -42
// Беззнаковая интерпретация при выводе
String unsignedString = Integer.toUnsignedString(signed);
System.out.println(unsignedString); // "4294967254" (для 32-битного int)
// Парсинг беззнаковой строки
int parsedUnsigned = Integer.parseUnsignedInt("4294967254");
System.out.println(parsedUnsigned); // -42 (хранится как знаковое, но интерпретировалось как беззнаковое)
// Сравнение в беззнаковом контексте
int a = -1;
int b = 1;
boolean unsignedCompare = Integer.compareUnsigned(a, b) > 0; // true, т.к. -1 как беззнаковое = 4 294 967 295
Важно: Сам тип int остаётся знаковым. Эти методы лишь меняют способ его интерпретации при выполнении конкретных операций.
Ответ 18+ 🔞
Так, слушай, вот сидишь ты, такой весь в себе, пишешь на Java, и тут тебе в голову стучится: "А примитивные-то типы — они знаковые или нет?". Ну, я тебе скажу, блядь, как отрезал — все они знаковые, ёпта! byte, short, int, long — вся эта братва использует старший бит под знак, как последний подлец. Могут и в плюс уйти, и в минус нырнуть.
Вот ихние диапазоны, держи:
byte: от -128 до 127 (маловато будет, конечно)short: от -32 768 до 32 767int: от -2³¹ до 2³¹-1 (уже теплее)long: от -2⁶³ до 2⁶³-1 (ну тут овердохуища, в рот меня чих-пых)
А как же беззнаковые, спросишь? А вот как, хитрая жопа! С Java 8 в обёртках (Integer, Long) подсуетились и добавили методы, чтобы интерпретировать эти знаковые числа как беззнаковые. Но сам-то тип, блядь, остаётся прежним, знаковым! Это как надеть на хуй в пальто — суть не меняется, но вид другой.
// Храним как есть, со знаком
int signed = -42;
System.out.println(signed); // -42 (всё честно)
// А теперь выведем, будто оно беззнаковое — фокус-покус!
String unsignedString = Integer.toUnsignedString(signed);
System.out.println(unsignedString); // "4294967254" (ёперный театр, да?)
// И обратно можно распарсить эту ахинею
int parsedUnsigned = Integer.parseUnsignedInt("4294967254");
System.out.println(parsedUnsigned); // -42 (опять вернулось к своему знаковому я)
// Самое весёлое — сравнение. Смотри, какой пиздец:
int a = -1;
int b = 1;
// Сравниваем как беззнаковые, и -1 вдруг становится гигантом!
boolean unsignedCompare = Integer.compareUnsigned(a, b) > 0; // true, потому что -1 как беззнаковое = 4 294 967 295
Короче, суть в чём: сам int — он как был мудаком знаковым, так и остался. А эти все toUnsignedString и compareUnsigned — они просто надевают на него шляпу и усы, чтобы он притворился беззнаковым красавчиком на время операции. Волшебство, блядь, да и только.