Подтвердить что ты не робот

Почему Java-аутобоксинг не распространяется на вызовы методов методов автобокс-типов?

Я хочу преобразовать примитив в строку, и я попробовал:

myInt.toString();

Ошибка с ошибкой:

int cannot be dereferenced

Теперь я получаю, что примитивы не являются ссылочными типами (т.е. не Object) и поэтому не могут иметь методы. Тем не менее, Java 5 представила автобоксинг и распаковку (a la С#..., который мне никогда не нравился на С#, но это не так). Таким образом, с помощью autoboxing, я ожидал бы, что вышеуказанное преобразует myInt в Integer, а затем вызовет toString().

Кроме того, я считаю, что С# допускает такой вызов, если не помню неправильно. Это просто неудачный недостаток спецификации автобоксинга/распаковки Java, или есть ли веская причина для этого?

4b9b3361

Ответ 1

Java autoboxing/unboxing не доходит до степени, позволяющей разыменовывать примитив, поэтому ваш компилятор предотвращает его. Ваш компилятор до сих пор знает myInt как примитив. Там есть статья об этой проблеме на jcp.org.

Автобоксирование в основном полезно при передаче или передаче параметров - позволяет вам передавать примитив как объект (или наоборот) или назначать примитив объекту (или наоборот).

Так что, к сожалению, вам нужно будет сделать это вот так: (Кудос Патрик, я переключился на ваш путь)

Integer.toString(myInt);

Ответ 2

То же, что сказал Джастин, но вы должны сделать это вместо этого:

Integer.toString(myInt);

Он сохраняет выделение или два и более читаем.

Ответ 3

Другой способ сделать это - использовать:

String.valueOf(myInt);

Этот метод перегружен для каждого примитивного типа и Object. Таким образом, вам даже не нужно думать о типе, который вы используете. Реализации метода вызовут подходящий метод данного типа для вас, например. Integer.toString(myInt).

См. http://java.sun.com/javase/6/docs/api/java/lang/String.html.

Ответ 4

кажется недостатком спецификации для меня

Есть больше недостатков, и это тонкая тема. Проверьте этот вне:

public class methodOverloading{
   public static void hello(Integer x){
      System.out.println("Integer");
   }

   public static void hello(long x){
      System.out.println("long");
   }

   public static void main(String[] args){
      int i = 5;
      hello(i);
   }
}

Здесь "long" будет напечатан (он сам не проверял), потому что компилятор расширяет возможности автобоксинга. Будьте осторожны при использовании автобоксинга или вообще не используйте его!

Ответ 5

Допустимый синтаксис, ближайший к вашему примеру,

((Integer) myInt).toString();

Когда компилятор заканчивается, это эквивалентно

Integer.valueOf(myInt).toString();

Однако это не работает так же, как и обычное использование, String.valueOf(myInt), потому что, за исключением особых случаев, он создает новый экземпляр Integer, а затем немедленно отбрасывает его, что приводит к ненужному мусору. (Небольшой диапазон целых чисел кэшируется и доступ через доступ к массиву.) Возможно, разработчики языка хотели отказать в этом использовании по соображениям производительности.

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

Ответ 6

В С# целые числа не являются ссылочными типами, и они не должны быть помещены в бокс для вызова ToString(). Тем не менее они являются рассмотренными объектами в Framework (как ValueType, поэтому имеют семантику значений). В CLR методы примитивов вызываются "косвенно", загружая их в стек (ldind).

Ответ 7

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

Также интересно: "autoboxing - это взлом на уровне компилятора" на Java. Автобоксинг - это, по сути, странный кладдж, добавленный на Java. этот пост для более подробной информации о том, как это странно.

Ответ 8

Было бы полезно, если бы Java определила некоторые статические методы для работы с примитивными типами и встроила в компилятор синтаксический сахар, чтобы

5.asInteger

будет эквивалентно

some.magic.stuff.Integer.asInteger(5);

Я не думаю, что такая функция может привести к несовместимости с любым кодом, который компилируется в соответствии с текущими правилами, и во многих случаях это поможет уменьшить синтаксический беспорядок. Если бы Java относилась к примитивам autobox, которые были разыменованы, люди могли предположить, что они отображали синтаксис разыменования на вызовы статических методов (что фактически происходит в .NET), и поэтому операции, написанные в этой форме, были не более дорогостоящими, чем эквивалентные вызовы статического метода. Добавление новой языковой функции, которая побуждала бы людей писать плохой код (например, автоматически-бокс-разыменованные примитивы), не кажется хорошей идеей, хотя могут быть использованы методы разметки.