Есть ли автоматический вывод типа в 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

Игры Brainiac
источник
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.

SimonC
источник
или вычисление 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());
}
самвел1024
источник