Есть ли автоматический вывод типа в Java?


113

Есть ли autoв Java такой тип переменной, как в C ++?

Пример:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Я знаю, что в Java есть расширенный цикл for, но есть ли автоматический? Если нет, есть ли какой-нибудь способ это сделать? Я имею в виду новую функцию в C ++ 11


1
Все, кроме основных типов, может быть присвоено переменной типа Object, поэтому для некоторых операций вы можете использовать Objectтам, где хотите auto.
Zyx 2000,

1
нет в java такой переменной нет
Алексей Булгак

@ Zyx2000: Тогда он будет использовать to_stringфункцию объекта , а не сам объект, не так ли?
Игры Brainiac

2
@GamesBrainiac: Нет, он будет использовать переопределенную версию, если она существует.
Кеппил

2
Термин, который вы ищете, не «авто», это «вывод типа». Есть довольно много вопросов о выводе типов в Java, хотя они в основном относятся к дженерикам, поэтому я не уверен, как найти дубликат ...

Ответы:


49

Ответили до того, как вопрос был ИЗМЕНИТЬ :

Нет, autoв Java нет типа переменной. Такой же цикл может быть получен как:

for ( Object var : object_array)
  System.out.println(var);

В Java есть локальные переменные, область видимости которых находится внутри блока, в котором они были определены. Подобно C и C ++, но нет ключевого слова auto или register. Однако компилятор Java не разрешит использование неявно инициализированной локальной переменной и выдаст ошибку компиляции (в отличие от C и C ++, где компилятор обычно выдает только предупреждение). Предоставлено: Википедия .

Нет, в Java нет такого массового вывода типов, как C ++. Был проведен RFE, но он был закрыт как "Не исправить" по следующей причине:

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


10
@GamesBrainiac Нет, вызовы методов в Java всегда полиморфны. Однако многие другие вещи (например, разрешение перегрузки или любая операция, которая не определена Object) не могут быть выполнены таким образом. Это не совсем хороший ответ, он работает только потому, что пример в вопросе слабый.

10
Этот вопрос касается вывода типа в C ++ 11, а не о старом использовании autoв C и до C ++ 11. Ваше редактирование не по теме.

4
"Это не то, что я имел в виду, как только вы наберете приведение к объекту, он даст вам to_string объекта" False. Абсолютно 100% ложное.
Луи Вассерман

140
«Люди выигрывают от избыточности». Это так. Каждое утро я просыпаюсь и думаю: «Как сделать свой код более избыточным?». Из-за преимуществ.
ahoffer

2
Более того, этот ответ устарел, потому что varэто зарезервированное ключевое слово, начиная с Java 9.
6infinity8

70

Возможно, в Java 10 есть то, что вы (и я) хотите, через varключевое слово.

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

Из предложений по расширению JDK 286


Обновление: Ага, эта функция появилась в версии Java 10!


6
Да, это улучшение, но это ключевое слово может работать только с локальными переменными. Не такой мощный, как автоматический вывод типов C ++
техасбрюс,

7
Мелкая придирка: varэто не ключевое слово! Из JLS : «var - это не ключевое слово, а скорее идентификатор со специальным значением как тип объявления локальной переменной». Таким образом, в отличие от ключевых слов, вам ничто не мешает вызвать переменную или метод «var».
Klitos Kyriacou

2
Хороший вопрос @KlitosKyriacou. Тем не менее, если я представлю себе замену «ключевого слова» на «идентификатор» - или даже «идентификатор со специальным значением в качестве типа объявления локальной переменной» - ответ, я думаю, будет менее ясным. Но да, varдействительно нет в списке ключевых слов.
sorrymissjackson

Это ключевое слово не только для обратной совместимости. Помимо того факта, что у вас может быть идентификатор с этим именем, var выполняет роль ключевого слова.
facetus

25

В Java 7 представлен ромбовидный синтаксис

Box<Integer> integerBox = new Box<>(); // Java 7

По сравнению со старой java

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

Внимательный читатель заметит, что этот новый синтаксис не помогает при написании циклов for в исходном вопросе. Это кажется правильным и полностью преднамеренным. См. Другой ответ, в котором упоминается база данных ошибок Oracle.


4
Верно, но то, что он (и я) ищем, это что-то вроде:, auto integerBox = new Box<Integer>();это обычно используется для получения возвращаемого значения из функций, которые иногда могут быть HashMap<String, LinkedList<Operation, Set<Integer>>>
сложными,

1
Именно к этой проблеме я обратился после примеров кода. Был сделан вывод, что Java этого не делает, и это сделано специально.
Tarrasch

18

В Java 8 вы можете использовать вывод лямбда-типа, чтобы не объявлять тип. Аналогом примеров вопрошающего может быть:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

оба из них также можно упростить с помощью ссылок на методы:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

8

Короче нет, автотипа нет. Если все, что вы делаете, это печатаете значение, вы можете просто ссылаться на значение как на Object.


или вычисление hashCodes, или сбор имен классов, или ... вы поняли;) Однако список короткий. См. Документацию класса Object (комментарий для начинающих, уверен, вы знали, SimonC)
Александр Малахов

5

Это не чистое решение для Java, однако добавление библиотеки под названием lombok позволит скомпилировать описанную ниже магию и работать очень похоже на autoключевое слово в C ++.

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.