Разница между int.maxvalue и int.minvalue? [Дубликат]

Что такое типы raw в Java и почему я часто слышу, что они не должны использоваться в новом коде?

blockquote>

Необработанные типы - это древняя история Java язык. В начале были Collections, и они больше не держали Objects и ничего меньше. Каждая операция на Collections требовала отличных от Object желаемого типа.

List aList = new ArrayList();
String s = "Hello World!";
aList.add(s);
String c = (String)aList.get(0);

Хотя это продолжалось большую часть времени, произошли ошибки

List aNumberList = new ArrayList();
String one = "1";//Number one
aNumberList.add(one);
Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here

Старый нетривиальные коллекции не могли обеспечить безопасность типов, поэтому программисту приходилось запоминать то, что он хранил в коллекции. Генераторы, изобретенные, чтобы обойти это ограничение, разработчик объявит сохраненный тип один раз, и компилятор сделает это вместо этого.

List aNumberList = new ArrayList();
aNumberList.add("one");
Integer iOne = aNumberList.get(0);//Compile time error
String sOne = aNumberList.get(0);//works fine

Для сравнения:

// Old style collections now known as raw types
List aList = new ArrayList(); //Could contain anything
// New style collections with Generics
List aList = new ArrayList(); //Contains only Strings

Более сложный Интерфейс Compareable:

//raw, not type save can compare with Other classes
class MyCompareAble implements CompareAble
{
   int id;
   public int compareTo(Object other)
   {return this.id - ((MyCompareAble)other).id;}
}
//Generic
class MyCompareAble implements CompareAble
{
   int id;
   public int compareTo(MyCompareAble other)
   {return this.id - other.id;}
}

Обратите внимание, что невозможно реализовать интерфейс CompareAble с compareTo(MyCompareAble) с необработанными типами. Почему вы не должны их использовать:

  • Любое Object, хранящееся в Collection, должно быть выполнено до его использования
  • Использование обобщений позволяет проверять время компиляции
  • Использование исходных типов - это то же самое, что и сохранение каждого значения как Object

Что делает компилятор: Дженерики обратно совместимы, они используют одни и те же классы java, типы делают.

List someStrings = new ArrayList();
someStrings.add("one");
String one = someStrings.get(0);

Будет скомпилирован как:

List someStrings = new ArrayList();
someStrings.add("one"); 
String one = (String)someStrings.get(0);

Это тот же код, который вы бы написали, если вы использовали исходные типы напрямую. Думаю, я не уверен, что происходит с интерфейсом CompareAble, я предполагаю, что он создает две функции compareTo, одна из которых принимает MyCompareAble, а другая принимает Object и передает ее первой после ее литья.

Каковы альтернативы сырым типам: используйте generics

7
задан BradleyDotNET 31 January 2014 в 21:41
поделиться

5 ответов

Это потому, что вычисления в правой части присваивания выполняются в виде целочисленного типа. И это переполняет целое число

Вы можете исправить это с помощью:

public const long MAXIMUM_RANGE_MAGNITUDE = int.MaxValue + (long)1; // or 1L

Путем литья хотя бы одного из операндов в long

Причина, по которой вы получаете ошибка указана в спецификациях C #.

См. раздел C # Specification Section 4.1.5 (Integral types)

Для двоичных файлов +, -, *, /,%, & amp; , ^, |, ==,! =,>, & lt ;,> = и & lt; = операторы, операнды преобразуются в тип T, где T является первым из int, uint, long и ulong, который может полностью представляют все возможные значения обоих операндов. Затем операция выполняется с использованием точности типа T, а типом результата является T (или bool для реляционных операторов). Недопустимо, чтобы один операнд имел длинный тип, а другой - тип ulong с бинарными операторами.

В вашем случае, поскольку оба операнда сложения могут быть представлены в int, поэтому вычисление выполняется в целочисленном типе. Явное литье одного из операндов в long приведет к результату long и, следовательно, не приведет к ошибке переполнения.

16
ответ дан Habib 20 August 2018 в 21:20
поделиться
  • 1
    .... или + 1L; – Tim Schmelter 31 January 2014 в 21:46
  • 2
    Отличный ответ, я попробовал пару вариантов кода, который вы опубликовали, но, по-видимому, не тот! Твоя прекрасно работает. – BradleyDotNET 31 January 2014 в 22:05

Я думаю, что это связано с вычислением значения int.MaxValue + 1 перед , сделанным актом long. Конечно, длинные могут удерживать значение, но поскольку вы выполняете целочисленное добавление, невозможно сохранить целочисленное значение int.MaxValue + 1 в int до тех пор, пока не будет выполнено литье.

1
ответ дан Justin C 20 August 2018 в 21:20
поделиться

Ваш код на самом деле выглядит следующим образом:

(long)(int.MaxValue + 1)

Но поскольку .Net framework имеет встроенное неявное преобразование между int и long, вам не нужно явно помещать листинг в ваш код.

Итак, во-первых, эта часть кода выполняется:

int.MaxValue + 1

, и результатом этой операции является значение int, которое вызывает и исключает переполнение. Таким образом, ваш код даже не имеет возможности начать преобразование из int в long.

4
ответ дан Paweł Bejger 20 August 2018 в 21:20
поделиться

try

public const long MAXIMUM_RANGE_MAGNITUDE = (long)int.MaxValue + 1L;
1
ответ дан Satpal 20 August 2018 в 21:20
поделиться
  • 1
    спасибо за редактирование. Я только пришел домой с работы. делать это – RadioSpace 1 February 2014 в 01:54

Приведите значение константы в длинное.

public const long MAXIMUM_RANGE_MAGNITUDE = (long) int.MaxValue + 1;
1
ответ дан Scott Corbett 20 August 2018 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: