• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Question Local Variable Scope

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The answer to the following from chapter 3 review question 8 surprise me

public class Ouch {

static int ouch = 7;
public static void main(String[] args) {
new Ouch().go(ouch);
System.out.print(" " + ouch);

}

void go (int ouch)
{

ouch++;
for(int ouch = 3; ouch < 6; ouch++ );
System.out.print(" " + ouch);
}

}

The answer is E Compilation fails. Since we are in the for loop, should the "go" method argument "ouch" be hidden by for-loop "ouch"? I know the answer is negative but why? Since the following WILL compile

public class Ouch {

static int ouch = 7;
public static void main(String[] args) {
new Ouch().go(ouch);
System.out.print(" " + ouch);

}

void go (int ouch)
{

ouch++;
for(int i = 3; i < 6; i++ );

int i = 2;

System.out.print(" " + i);
}

}

The point is I also defined the variable 'i' twice. However, the following will fail


public class Ouch {

static int ouch = 7;
public static void main(String[] args) {
new Ouch().go(ouch);
System.out.print(" " + ouch);

}

void go (int ouch)
{

ouch++;

int i = 2;

for(int i = 3; i < 6; i++ );



System.out.print(" " + i);
}

}

Note that I define variable i before the for loop.

Thank you for your help

-Cheung

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cheung,

In the book example you provided, the compilation fails because ouch is already in scope prior to the for loop which attempts to declare a variable that has the same name.


In this example a variable i is declared in the for loop, and when it goes out of scope the variable name is available again.


This example fails for the same reason the book example failed, i is already in scope when the for loop attempts to create a variable of the same name.



I too am studying for the SCJP.....so I hope I did not miss anything in this example.
 
Ranch Hand
Posts: 317
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Cheung,

please put the code within the code brackets. It's hard to read your code.

cheers
Bob
 
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The loop variable in the for loop has scope only inside the for loop. This would fail to compile



So that's why when I do this



I'm not re-declaring i on (1). There is no i defined at that point. Also I think you need to try something like this to be completely clear about scopes of variables

 
Cheung Chau
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,

Thank you for your reply. Sorry Bob, I will put my code in code block next time (this time).

Hi Jim,

I am totally agree with your explaination on why it failed and that was reason I posted a different example that derived from the review question. However, the real question I would like to get at is whether variable ouch defined in the for loop should hide the method argument and why not?



As you can see, static variable ouch at 1. was hidden by local variable ouch at 2. My question is why CAN'T for-loop variable ouch at 3.(which also is a local variable) hide the local variable ouch at 2. If you read Ankit's reply we see that variable i defined in for-loop ONLY exist in the for-loop and so I believe for-loop does form a scope. If the for-loop forms a scope, why can it hide a variable. That's my original question

Again, I know this is the fact. However, I wonder if there is a logical explaination.


Ankit,

Thank you for your reply. Please see my comment above and see if you can offer more insight. Thank

-Cheung
 
Jim Toy
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cheung,

I think I understand you better now. As to the why, the for loop is block scoped, but has to honor method scoped variables.

My apologies if this is more than necessary ... i did this more for my benefit of working out the problem. The variable defined in the for loop will not hide/shadow because the for block does not begin until after the for statement, so the variable initialized cannot conflict with others in the block.

Here is an example I created....hopefully i commented it correctly

edit: By the way, I am really glad you posted this thread, it made me really think about scoping.



Line 8 is OK, it is a shadow, line 10 will fail, line 15 is ok because there is no other variable named 'free' in the block.

From the K&B book pg 191 there are 4 scope types:
* static, class level
* instance, object level
* local , method level
* block , block level

The question that jumps to my mind is ...why is it ok to declare ouch on line 18. I would say it is because it is method level scoped, and when the method is in scope on the stack arguments are passed by value. So even though the method is free to extend beyond itself to the reference static/instance variables it still has the flexibility to re declare those names since they are not in scope.

 
Cheung Chau
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jim,

Thank you for taking the time. Again, "WHY" is what I am going for here. I did work out the logic you stated perfectly in your example before my original post - that's why you see the extra example I posted with variable i. What I mean is I would probably answer a similar question correctly in the exam. However, I am interested in knowing the following - let's say we have

1) static scope
2) instance scope
3) local scope
4) block scope

Variable in local scope will hide a variable with the same name in either static or instance scope, but block scope variable CANNOT do the same thing to local scope variable. WHY? Again, I did get the fact but just need a logical explaination.

I couldn't find any detail on this in the book.

Sorry guys, this may not be the right forum to post this question because this is not about getting the exam question but learning Java. However, the question did derived from one of the review question. Thank you for your reply and assisstance.

-Cheung
 
Cheung Chau
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jim,

Sorry that I missed all the comment you made below your code block. However, I am still not very clear on what you mean by

I would say it is because it is method level scoped, and when the method is in scope on the stack arguments are passed by value. So even though the method is free to extend beyond itself to the reference static/instance variables it still has the flexibility to re declare those names since they are not in scope

Can you clarify?

Here is my take on this - all local variables are defined on the stack and the stack won't allow code to define variable in the inner block with the same name outside that block. However, unlike static and instance variable, the order matters which mean the inner block won't see the any variable define after the inner block. This make define variable after the block with same name okay.

I don't like the definition above becuase I made it up on the fly based on the review question. I wonder if anyone can offer a more logical and accurate explaination.

Thank you

-Cheung



 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Like I think somebody said, the block has to honor the scope in which it occurs.

If a block in a method declares a variable, that variable is scoped only to the block.

The method can subsequently declare a variable of the same name and type.

But if the method declares the variable before the block attempts to declare it,
the block version will cause a compiler error.

So you listed the various scopes there and I imagine you're wondering why this is so. I think
it is because those scopes are not necessarily independent of eachother. At least here we see
that the block scope can be controlled by the method scope in which it occurs, depending on
the order of the declarations.
 
Cheung Chau
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ken,

Thank you for your post. I wonder if you can extend on what you mean by scopes may be independent of each other.

Hi all,


Let's see if we can put a closure to this post. The following is directly from our Java Language Specification

http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html

Here is the part (directly from the language spec), I think (kind of) explain what we have here

If a declaration of an identifier as a local variable of the same method, constructor, or initializer block appears within the scope of a parameter or local variable of the same name, a compile-time error occurs.

Thus the following example does not compile:




This restriction helps to detect some otherwise very obscure bugs. A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well. Hence, the following example compiles without error:



On the other hand, local variables with the same name may be declared in two separate blocks or for statements neither of which contains the other. Thus:



compiles without error and, when executed, produces the output:

0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1


I said "kind of" because I am still not totally sure about the following statement from the doc

If a declaration of an identifier as a local variable of the same method, constructor, or initializer block appears within the scope of a parameter or local variable of the same name, a compile-time error occurs.



I hope someone can put in plain English. That's why I've always preferred Head First Java or Core Java over the formal Java specification



-Cheung
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The statement you quoted is pretty awkward, but it breaks down to:

If a variable declaration that appears in a method,constructor, or initializer block (ie a local variable)
is within the scope of another local variable and has the same name, there will be a compiler error.

In your example, the block variable is declared within a method that previously declared a same-typed
variable of the same name. This falls under the rule above. But the rule above does not address the
case where a block variable is declared within a method that subsequently declares a same-type,same-
name variable as a local variable (outside of the block). This compiles, but we would definately say that
the scope of the block variable (in the second case) is within the scope of the local variable, because the
scope of the local variable is the entire method. It appears that a local variable's scope
is not the entire method in which it is declared, but only the part of the method that is defined *after* the
local variable is first declared. That understanding is consistent with the sentence from the language spec
that you first quoted.

Ken
reply
    Bookmark Topic Watch Topic
  • New Topic