Why do I need to declare a type within Foreach?

9

Why in%% we need to always declare a variable.

Example:

   for(Pessoa pessoa : pessoas) {
    //qualquer coisa 
   }

In other words, I want to know why you can not do this:

  Pessoa pessoa;
  for(pessoa : pessoas) {
      //qualquer coisa
  }
    
asked by anonymous 02.02.2016 / 01:18

3 answers

7

The code

ArrayList textos = new ArrayList<String>();
textos.add("texto1");
textos.add("texto2");
for (String t : textos) {
    System.out.println(t);
}

It's actually compiled like this:

ArrayList textos = new ArrayList<String>();
textos.add("texto1");
textos.add("texto2");
for (Iterator<String> it = textos.iterator(); it.hasNext();) {
    String t = it.next();
    System.out.println(t);
}

If you put the statement out, it would look like? So?

    ArrayList textos = new ArrayList<String>();
    textos.add("texto1");
    textos.add("texto2");
    String t = it.next();
    for (Iterator<String> it = textos.iterator(); it.hasNext();) {
        System.out.println(t);
    }

Try to compile and see if it works.

Can the compiler be smart to figure out a way to solve this? You can. But they preferred not to complicate it to a small and debatable advantage.

Of course you can do this:

ArrayList textos = new ArrayList<String>();
textos.add("texto1");
textos.add("texto2");
String t;
for (Iterator<String> it = textos.iterator(); it.hasNext();) {
    t = it.next();
    System.out.println(t);
}

Simple, right? Think of a more complex example where the compiler would have to look at other snippets of the code to see if everything is okay, otherwise it will not affect anything.

Another important point is that foreach was created to go from beginning to end of a data sequence. It was created to avoid bugs that the programmer could cause trying to iterate out of the standard. Why would you want a specific data - the last one - to escape the loop? Only the last need could be accessed outside the loop. If you need to do this, better be explicit and put in a variable. It is unlikely to be worth creating such a large compiler complication and it kills one of the advantages of foreach to solve a case that is rarely used and can always be avoided.

In the end, it was just a decision made. Nothing prevents language from allowing this. Just not worth the effort.

    
02.02.2016 / 01:49
6

The simple answer: Because the specification requires that the value used in for-each is declared in it .

Developing a little, language designers have decided on this model for simplicity - this block works for most cases, and the compiler does not have to worry about the variable "escaping" from the loop. There are several scenarios that do not work with this constraint (access the value of the variable iterated after the end of the loop, modifications in the iterator, iteration of multiple variables at the same time / in parallel). But whoever specified this feature felt that building simplicity was more important than meeting all scenarios.

    
02.02.2016 / 01:42
3

Just to complement, I'll put what the @ Sorrow spoke on the link that @DiegoFelipe posted

 private static void testForEach(ArrayList<String> als) {
  for(String s: als)
    System.out.println(s);
 }

 private static void testIterator(ArrayList<String> als) {
  for(Iterator<String> is = als.iterator(); is.hasNext();) {
   String s = is.next();
   System.out.println(s);
  } 
 }

There it says that both iterations present the same Bytecode and that by all indications the first option is (or appears to be) only one form of Syntactic Sugar.

    
02.02.2016 / 01:46