0

I have found the following java code:

test:
    for (int i = 0; i <= max; i++) {
        int n = substring.length();
        int j = i;
        int k = 0;
        while (n-- != 0) {
            if (searchMe.charAt(j++) != substring.charAt(k++)) {
                continue test;
            }
        }
        foundIt = true;
            break test;
    }
    System.out.println(foundIt ? "Found it" : "Didn't find it");
}

Inside the loop, the above code is creating 'n', 'j' and 'k' several times. How the program distinguishes between these variables of the same name?

I mean where they are stored in the memory to distinguish them?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
user2994783
  • 141
  • 1
  • 10
  • 3
    `n`, `j`, and `k` are all only declared once per loop. At the end of the loop they pass out of scope and are illegible for garbage collection. On the next iteration of the loop, new variables are created. Variable names are almost non existent in bytecode, so the fact that they have the same name through different iterations doesn't matter – GBlodgett Jan 15 '19 at 18:24
  • Related: [Java - Declaring variables in for loops](https://stackoverflow.com/questions/4501482/java-declaring-variables-in-for-loops) – Ole V.V. Jan 15 '19 at 18:26
  • 1
    I'd also look at: [How does Java associate a variable name with a location in memory?](https://stackoverflow.com/questions/16528093/how-does-java-associate-a-variable-name-with-a-location-in-memory) – GBlodgett Jan 15 '19 at 18:27
  • As an ordinary programmer we don’t need to concern ourselves with where in memory Java puts our variables. Just trust that, say, your variable `n` exists from the declaration and down to the closing curly brace. Then it doesn’t exist any more, so the next time through the loop there is no confusion possible when a new `n` is created. – Ole V.V. Jan 15 '19 at 18:29
  • 1
    @GBlodgett they're not eligible for garbage collection: these are primitive local variables, and thus are on the stack. – Andy Turner Jan 15 '19 at 18:35
  • @AndyTurner [It appears you are correct](https://stackoverflow.com/questions/18746801/are-java-primitives-garbage-collected). Thanks for teaching me something new! – GBlodgett Jan 15 '19 at 18:41
  • `the above code is creating 'n', 'j' and 'k' several times` -- No, this is not true. There is only one of each variable. The code _assigns_ those variables multiple times. – mbj Jan 15 '19 at 18:50
  • Thanks. Good answers. As a teacher, I must know if the variables with same name are being created and the compiler is not giving error. I think previously we used to get error on such variable declarations. @Andy do you mean Garbage collection is done only for objects? What about String enclosed in function arguments? Like some people write passwords as String arguments. – user2994783 Jan 15 '19 at 18:54
  • This kind of declaration has never resulted in compile error. And yes, garbage collection happens only for _objects_ allocated with the `new` operator. In Java, method calls always pass parameter values _by value_, on the stack. Parameters, and also local variables, are merely named locations relative to the _stack frame_ of the current method invocation. – mbj Jan 16 '19 at 06:36
  • A variable/parameter declared to be of a _primitive type_, such as `int`, has its value stored directly in the corresponding location on the stack. For _reference types_, such as `String`, the stack location instead contains a _reference_ to data located somewhere else in memory (or `null`, if that data doesn't exist). – mbj Jan 16 '19 at 06:39

2 Answers2

1

With a bit of simplification:

Inside a { ... } block, int k = 0; creates a variable, and that variable exists up to the moment where you reach the end of the block, and there the variable gets destroyed. So, at any time during the program run, there's at most one n, j, or k in existence.

A bit closer to reality:

The compiler scans the whole method, finds the list of variables that might exist in parallel (i, n, j, k, and foundIt), and allocates enough places on the stack for these variables (5 places in your example). These stack places exist from the moment you enter your method until you return from it, but they are not used all the time, e.g. the k place only contains useful values from the time you execute int k = 0; to the end of the current loop iteration.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7
0

Java's local variables have a protection known as definite assignment this means that you can't read a value from them before you've assigned it a value.

They are also defined within a scope: you can only access the variable within a certain chunk of the program.

With the two of these things together, you don't need a separate variable for each iteration of the loop: you are guaranteed to assign a local variable a value before using it, so you are guaranteed to overwrite any value which was stored in it before, if any.

Variables are really just a helpful concept in the source code. Once compiled, the byte code doesn't have variable names: the compiler has simply determined that it can temporarily use a particular part of memory to store a value for a limited time. It will reuse this memory many times, but in ways that it guarantees do not overlap between usages.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243