2008-08-07 10 views
46

Я хочу, чтобы преобразовать примитивно в строку, и я попробовал:Почему автооблок Java не распространяется на вызовы методов методов с автобоксами?

myInt.toString(); 

Это терпит неудачу с ошибкой:

int cannot be dereferenced 

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

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

ответ

44

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

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

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

Integer.toString(myInt); 
26

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

Integer.toString(myInt); 

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

8

seems like a shortcoming of the specification to me

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

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); 
    } 
} 

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

14

Еще один способ сделать это состоит в использовании:

String.valueOf(myInt); 

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

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

0

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

4

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

((Integer) myInt).toString(); 

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

Integer.valueOf(myInt).toString(); 

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

Редактировать: Я был бы признателен, если бы downvoter (ы) прокомментировали бы, почему это не помогает.

+1

Я хочу всех, кто голосовал бы после голосования, прокомментировал, почему что-то проголосовало. Я всегда делаю это, если это не очевидно (например, ответ абсолютно неправильный или бессмысленный). – 2008-11-12 22:49:59

0

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

Также интересно: "autoboxing is a compiler-level hack" на Java. Автобоксинг - это, по сути, странный кладдж, добавленный на Java. Зайдите в this post для получения более подробной информации о том, как это странно.

0

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

5.asInteger 

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^