wood burning stoves*
The moose likes Beginning Java and the fly likes scope of local variables Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "scope of local variables" Watch "scope of local variables" New topic
Author

scope of local variables

Vinod Venkatasubramanian
Greenhorn

Joined: Oct 19, 2003
Posts: 13
I am curious as to why one of the following works while the other does not:
The following compiles fine:

Note that 's' and 'x' have be redefined in the outer scope.
The following throws a compile-time error ("s is already defined in main(java.lang.String[])"):

Can anyone explain why ?
[ edited to add and preserve formatting using the [code] and [/code] UBB tags -ds ]
[ October 20, 2003: Message edited by: Dirk Schreckmann ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Because in the second example, s is already defined, whereas in the first it isn't (it is only defined in the inner block), so it seems to me. Don't you agree?


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Vinod Venkatasubramanian
Greenhorn

Joined: Oct 19, 2003
Posts: 13
Iam not sure. As far as the compiler is concerned, there are only 2 scopes - the outer and inner one - I dont think there is a line-by-line parse which makes one scenario work and not the other.
A similar piece on C++ would work fine, wherever we put the definition in the outer scope. But in C++ you also have the scope resoultion operator (: to decide which one to refer to... not so in Java.
Putting what you said in other words - in the 2nd scenario, when the 's' is redefined in the inner scope, the one in the outer scope is still "in-scope". But this is not the case in the 1st scenario - by the time we reach the 's' in the outer scope, the one in the inner scope is already "out-of-scope". This seems to make sense...
Lets see if someone has any other view on it.
Thanks anyway !
[ October 19, 2003: Message edited by: Vinod Venkatasubramanian ]
Derek Baker
Ranch Hand

Joined: May 23, 2003
Posts: 46
That's totally contrary to what I thought about scopes.
I'd be interested to hear any input anyone has.
Wayne L Johnson
Ranch Hand

Joined: Sep 03, 2003
Posts: 399
From the "Java Language Specification",

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:
class Test {
public static void main(String[] args) {
int i;
for (int i = 0; i < 10; i++)
System.out.println(i);
}
}

So a local variable in a method can "shadow" an instance variable [as in your first example], but a local variable can NOT "shadow" another local variable [as in your second example]. Why? Because that's what the language designer chose.
If you want to do more research, look at Java Language Specification.
[ October 20, 2003: Message edited by: Wayne L Johnson ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Wayne L Johnson:
So a local variable in a method can "shadow" an instance variable [as in your first example]

The first example also has two local variables - notice the unusual, but legal, use of a block at the start of the method.
Wayne L Johnson
Ranch Hand

Joined: Sep 03, 2003
Posts: 399
Ilja is correct ... I didn't look at the indentation carefully enough. The use of CODE tags would have helped, but mea culpa.
Java requires that you declare a local variable before it is referenced, whether it be at the beginning of a method or further down.
In the first example the String "s" is initially declared within a local block, so when when the block ends it goes out of scope. So there is no "s" in scope when the second declaration comes along, making it legal.
In the second example the String "s" is declared at the beginning of the method, so its scope is the entire method. As I stated [poorly] in my previous reply, you can not shadow a local variable, so even though the second declaration is within a local block, it is in violation of the Java language specification.
Better explanation, I hope.
Herb Schildt
Author
Ranch Hand

Joined: Oct 01, 2003
Posts: 239
I agree with Wayne's second post. In the first example, s is declared inside a block that ends before the second s is declared. Thus, as Wayne states, the first s goes out-of-scope before the second s is declared. Thus, no conflicts.
However, in the second example, the first s preceeds the block. Because an inner scope incorporates all of the names currently declared by an enclosing scope, the attempt to create an s locale to the block fails because of the name conflict with the pre-exsting s.


For my latest books on Java, including my Java Programming Cookbook, see HerbSchildt.com
Vinod Venkatasubramanian
Greenhorn

Joined: Oct 19, 2003
Posts: 13
Thanks everyone for pitching in !!!
Wayne, what you said seems to make sense... I was suspecting something similar (as in my second post) but could not put it in proper words.
I went throught the JLS and now its much clearer...
Coming from a C++ background (where both scenarios would work), guess I was expecting something else.
If you wonder WHY they made the specification like this, it might have to do with the fact that in Java, objects are not DESTROYED once they are out-of-scope.. they are only garbage collected. Whereas in C++, the 's' in the inner scope is destroyed once it has no meaning (ie, once that scope is exited)
Thanks again ! Appreciate your contributions a lot.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Vinod Venkatasubramanian:
If you wonder WHY they made the specification like this, it might have to do with the fact that in Java, objects are not DESTROYED once they are out-of-scope.. they are only garbage collected. Whereas in C++, the 's' in the inner scope is destroyed once it has no meaning (ie, once that scope is exited)

I don't think this decision has any technical reason - it should have been easy to implement the C++ way.
I guess the true reason is that shadowing local variables (especially when done accidentally) can lead to nasty bugs and maintenance burdens, so they prevented it by not allowing to do it.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: scope of local variables
 
Similar Threads
Head first Java - Chapter 4 Pool Puzzle p.91
Just a weird doubt
why is the below code not printing 2 i agree its a post increment but its being assigned to x???
Getting the type of variable instance
Comparision