В чем разница между int и Integer в Java и C #? - PullRequest
244 голосов
/ 03 августа 2008

Я читал Еще Джоэл о программном обеспечении , когда я наткнулся на Джоэл Спольски , говоря что-то о конкретном типе программиста, знающего разницу между int и Integer в Java / C # (объектно-ориентированные языки программирования).

Так в чем же разница?

Ответы [ 25 ]

234 голосов
/ 03 августа 2008

В Java тип 'int' является примитивом, а тип 'Integer' является объектом.

В C #, тип 'int' такой же, как System.Int32, и тип значения (т. Е. Больше похоже на java 'int'). Целое число (как и любые другие типы значений) может быть в штучной упаковке («обернуто») в объект.


Различия между объектами и примитивами несколько выходят за рамки этого вопроса, но подытожим:

Объекты предоставляют возможности для полиморфизма, передаются по ссылке (или, точнее, имеют ссылки, переданные по значению) и выделяются из кучи . И наоборот, примитивы являются неизменяемыми типами, которые передаются по значению и часто выделяются из стека .

.
148 голосов
/ 03 августа 2008

Ну, в Java int - это примитив, а Integer - это объект. Это означает, что если вы создали новое целое число:

Integer i = new Integer(6);

Вы можете вызвать какой-нибудь метод для i:

String s = i.toString();//sets s the string representation of i

В то время как с int:

int i = 6;

Вы не можете вызывать какие-либо методы для него, потому что это просто примитив. Итак:

String s = i.toString();//will not work!!!

выдаст ошибку, потому что int не является объектом.

int - один из немногих примитивов в Java (наряду с char и некоторыми другими). Я не уверен на 100%, но я думаю, что объект Integer более или менее просто имеет свойство int и целый набор методов для взаимодействия с этим свойством (например, метод toString ()). Так что Integer - это модный способ работы с int (точно так же, как, возможно, String - это модный способ работы с группой символов).

Я знаю, что Java - это не C, но, поскольку я никогда не программировал на C, это самый близкий мне ответ. Надеюсь, это поможет!

Целочисленный объект javadoc

Сравнение целочисленных объектов и примитивов int

37 голосов
/ 03 августа 2008

Я добавлю к превосходным ответам, приведенным выше, и расскажу о боксе и распаковке и о том, как это применимо к Java (хотя в C # это тоже есть). Я буду использовать только терминологию Java, потому что я больше au fait с этим.

Как уже упоминалось в ответах, int - это просто число (называемое распакованный тип ), тогда как Integer - это объект (который содержит число, следовательно, в штучной упаковке тип). В терминах Java это означает (кроме невозможности вызова методов в int), вы не можете хранить int или другие необъектные типы в коллекциях (List, Map и т. Д.). Чтобы сохранить их, вы должны сначала упаковать их в соответствующий тип в штучной упаковке.

В Java 5 и более поздних версиях есть что-то, что называется auto-boxing и auto-unboxing , что позволяет выполнять бокс / распаковку за кулисами. Сравните и сопоставьте: версия Java 5:

Deque<Integer> queue;

void add(int n) {
    queue.add(n);
}

int remove() {
    return queue.remove();
}

Java 1.4 или более ранняя версия (без универсальных шаблонов):

Deque queue;

void add(int n) {
    queue.add(Integer.valueOf(n));
}

int remove() {
    return ((Integer) queue.remove()).intValue();
}

Следует отметить, что, несмотря на краткость в версии Java 5, обе версии генерируют идентичный байт-код. Таким образом, хотя автоматическая упаковка и автоматическая распаковка очень удобны, поскольку вы пишете меньше кода, эти операции do выполняются за кулисами, с одинаковыми затратами времени выполнения, поэтому вам все равно нужно знать об их существовании.

Надеюсь, это поможет!

28 голосов
/ 04 августа 2008

Я просто напишу здесь, так как некоторые другие сообщения немного неточны по отношению к C #.

Правильно: int - это псевдоним System.Int32.
Неправильно: float - это не псевдоним для System.Float, а для System.Single

По сути, int является зарезервированным ключевым словом в языке программирования C # и является псевдонимом для типа значения System.Int32.

float и Float, однако, не совпадают, так как правильный тип системы для '' float '' - System.Single. Есть такие типы, которые зарезервировали ключевые слова, которые, кажется, не совпадают с именами типов напрямую.

В C # нет разницы между '' int '' и '' System.Int32 '' или любыми другими парами или ключевыми словами / системными типами, за исключением случаев определения перечислений. С помощью перечислений вы можете указать используемый объем хранилища, и в этом случае вы можете использовать только зарезервированное ключевое слово, а не имя типа среды выполнения системы.

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

Это объявление в методе:

int i;

определяет переменную i типа System.Int32, находящуюся в регистре или в стеке, в зависимости от оптимизации. Одно и то же объявление в типе (структура или класс) определяет поле члена. То же объявление в списке аргументов метода определяет параметр с теми же параметрами хранения, что и для локальной переменной. (обратите внимание, что этот абзац недействителен, если вы начнете использовать методы итератора в миксе, это совершенно разные звери)

Чтобы получить объект кучи, вы можете использовать бокс:

object o = i;

это создаст коробочную копию содержимого i в куче. В IL вы можете получить доступ к методам объекта кучи напрямую, но в C # вам нужно привести его обратно к int, который создаст другую копию. Таким образом, объект в куче не может быть легко изменен в C # без создания новой коробочной копии нового значения int. (Тьфу, этот абзац не так легко читается.)

19 голосов
/ 06 августа 2008

В Java есть два основных типа в JVM . 1) примитивные типы и 2) ссылочные типы. int является примитивным типом, а Integer является типом класса (который является типом ссылочного типа).

Примитивные значения не разделяют состояние с другими примитивными значениями. Переменная, тип которой является примитивным типом, всегда содержит примитивное значение этого типа.

int aNumber = 4;
int anotherNum = aNumber;
aNumber += 6;
System.out.println(anotherNum); // Prints 4

Объект - это динамически создаваемый экземпляр класса или массив. Ссылочные значения (часто просто ссылки) являются указателями на эти объекты и специальной нулевой ссылкой, которая не ссылается ни на один объект. На один и тот же объект может быть много ссылок.

Integer aNumber = Integer.valueOf(4);
Integer anotherNumber = aNumber; // anotherNumber references the 
                                 // same object as aNumber

Также в Java все передается по значению. Для объектов передаваемое значение является ссылкой на объект. Итак, еще одно различие между int и Integer в Java заключается в том, как они передаются в вызовах методов. Например, в

public int add(int a, int b) {
    return a + b;
}
final int two = 2;
int sum = add(1, two);

Переменная two передается как примитивный целочисленный тип 2. Тогда как в

public int add(Integer a, Integer b) {
    return a.intValue() + b.intValue();
}
final Integer two = Integer.valueOf(2);
int sum = add(Integer.valueOf(1), two);

Переменная two передается как ссылка на объект, который содержит целочисленное значение 2.


@ WolfmanDragon: Передача по ссылке будет работать так:

public void increment(int x) {
  x = x + 1;
}
int a = 1;
increment(a);
// a is now 2

Когда вызывается приращение, он передает ссылку (указатель) на переменную a . А функция increment напрямую изменяет переменную a .

А для типов объектов это будет работать следующим образом:

public void increment(Integer x) {
  x = Integer.valueOf(x.intValue() + 1);
}
Integer a = Integer.valueOf(1);
increment(a);
// a is now 2

Вы видите разницу сейчас?

19 голосов
/ 06 августа 2008

Что касается Java 1.5 и autoboxing , при сравнении объектов Integer возникает важная "причуда".

В Java объекты Integer со значениями от -128 до 127 являются неизменяемыми (то есть для одного конкретного целочисленного значения, скажем, 23, все объекты Integer создаются в вашей программе со значением 23, которое указывает на точное тот же объект).

Пример, это возвращает true:

Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //  true

Пока возвращается false:

Integer i1 = new Integer(128);
Integer i2 = new Integer(128);
System.out.println(i1 == i2); //  false

== сравнивает по ссылке (переменные указывают на один и тот же объект).

Этот результат может отличаться или не различаться в зависимости от того, какую JVM вы используете. Спецификация autoboxing для Java 1.5 требует, чтобы целые числа (от -128 до 127) всегда помещались в один и тот же объект-оболочку.

Решение? =) При сравнении объектов Integer всегда следует использовать метод Integer.equals ().

System.out.println(i1.equals(i2)); //  true

Больше информации на java.net Пример на bexhuff.com

11 голосов
/ 03 августа 2008

В C # int это просто псевдоним для System.Int32, строка для System.String, двойная для System.Double и т. Д. *

Лично я предпочитаю int, string, double и т. Д., Потому что они не требуют оператора using System; :) Глупая причина, я знаю ...

9 голосов
/ 31 июля 2014

Существует множество причин для использования классов-оболочек:

  1. Мы получаем дополнительное поведение (например, мы можем использовать методы)
  2. Мы можем хранить нулевые значения, тогда как в примитивах мы не можем
  3. Коллекции поддерживают хранение объектов, а не примитивов.
8 голосов
/ 11 декабря 2011

int используется для объявления примитивной переменной

e.g. int i=10;

Целое число используется для создания ссылочной переменной класса Integer

Integer a = new Integer();
8 голосов
/ 31 января 2009

В таких платформах, как Java, int s являются примитивами, а Integer является объектом, который содержит целочисленное поле. Важным отличием является то, что примитивы всегда передаются по значению и по определению являются неизменными.

Любая операция с примитивной переменной всегда возвращает новое значение. С другой стороны, объекты передаются по ссылке. Кто-то может утверждать, что точка на объект (AKA ссылка) также передается по значению, а содержимое - нет.

...