Чи існує автоматичний підхід до типу 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 є розширений цикл, але чи є авто? Якщо ні, чи є хак для цього? Я маю на увазі нову функцію в C ++ 11


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

1
жодна java не має такої змінної
Олексій Булгак

@ Zyx2000: Тоді він буде використовувати to_stringфункцію об'єкта , а не фактичний предмет, про який йдеться, чи не так?
Ігри Brainiac

2
@GamesBrainiac: Ні, він використовуватиме перекриту версію, якщо така існує.
Keppil

2
Термін, який ви шукаєте, не є "авто", це "висновок типу". Існує досить багато питань щодо виводу типу Java на Java, хоча вони в основному стосуються дженерики, тому я не знаю, як знайти дублікат ...

Відповіді:


49

Відповів , перш ніж питання було EDITED :

Ні, немає autoзмінного типу на Java. Таку саму петлю можна досягти як:

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

У Java є локальні змінні, сфера дії яких знаходиться в блоці, де вони були визначені. Схожий на C і C ++, але немає ключового слова для автоматичного або реєстрації. Однак компілятор Java не дозволить використовувати не явно ініціалізовану локальну змінну і дасть помилку компіляції (на відміну від C і C ++, де компілятор зазвичай лише попереджає). Люб’язно: Вікіпедія .

Ні, у Java не існує жодного основного типу виводу на зразок C ++. Існував RFE, але це було закрито, оскільки "Не виправлять", причина була така:

Люди отримують переваги надмірності декларації типу двома способами. По-перше, резервний тип слугує цінною документацією - читачам не потрібно шукати декларацію getMap (), щоб дізнатися, який тип вона повертає. По-друге, надмірність дозволяє програмісту оголосити призначений тип і, таким чином, скористатися перехресною перевіркою, виконаною компілятором.


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

10
Це питання стосується виводу типу C ++ 11, а не старого використання autoC та pre-C ++ 11. Ваша редакція поза темою.

4
"Це не те, що я мав на увазі, коли ви введете його на Об'єкт, він дасть вам тотостріг" Об'єкт "Неправдиво. Абсолютно 100% помилково.
Луї Вассерман

140
"Люди отримують користь від надмірності". Це правда. Кожного ранку я прокидаюся і думаю "як я можу зробити свій код більш зайвим?". Через переваги.
ahoffer

2
Більше того, ця відповідь застаріла, оскільки varце зарезервоване ключове слово, починаючи з Java 9.
6infinity8

69

Можливо, у Java 10 є те, що ви (і я) хочете, за допомогою varключового слова.

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

З пропозицій щодо вдосконалення JDK 286


Оновлення: Так , ця функція перетворилася на реліз Java 10!


6
Я його вдосконалення, але це ключове слово може працювати лише з локальними змінними. Не настільки потужний, як автоматичний висновок типу C ++
texasbruce

7
Незначний добір: varце не ключове слово! З JLS : "var - це не ключове слово, а скоріше ідентифікатор зі спеціальним значенням як тип декларації локальної змінної". Таким чином, на відміну від ключових слів, ніщо не заважає вам називати змінну чи метод "var".
Клітос Кіріако

2
Хороший момент @KlitosKyriacou. Тим не менш, якщо я уявляю собі замінити "ключове слово" на "ідентифікатор" - або навіть "ідентифікатор зі спеціальним значенням як тип локальної декларації змінної" - я думаю, що відповідь буде менш зрозумілою. Але так, varнасправді немає у списку ключових слів.
sorrymissjackson

Це не ключове слово лише для зворотної сумісності. Крім того, що ви можете мати ідентифікатор з цим іменем, var виконує роль ключового слова.
facetus

25

Java 7 представляє синтаксис алмазів

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

У порівнянні зі старою явою

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

Критичний читач помітить, що цей новий синтаксис не допомагає писати цикли для початкового запитання. Це правильно і цілком навмисно, здається. Дивіться іншу відповідь, що цитує базу даних про помилки Oracle.


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

1
Це стурбованість саме те, про що я звертався після зразків коду. Висновок полягав у тому, що Java цього не робить, і це задумано.
Тарраш

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, або збирання назв класів, або ... ви отримали ідею;) Список, однак, короткий. Дивіться документи "Об'єкт класу" (коментар призначений для початківців, я впевнений, ви це знали SimonC)
Олександр Малахов

4

Це не чисте рішення 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.