简体   繁体   中英

Java: “cannot find symbol” error of a String[] defined within a while-loop

Here's the relevant code:

public static String[] runTeams (String CPUcolor) 
{  
    boolean z = false ; 
    //String[] a = new String[6] ; 
    boolean CPU = false ; 
    while (z == false) 
    { 
        while (CPU==false) 
        {
            String[] a = assignTeams () ; 
            printOrder (a) ;

            for (int i = 1; i<a.length; i++) 
            { 
                if (a[i].equals(CPUcolor)) CPU = true ;
            }
            if (CPU==false) 
            {
                System.out.println ("ERROR YOU NEED TO INCLUDE THE COLOR OF THE CPU IN THE TURN ORDER") ; 
            }
        }
        System.out.println ("is this turn order correct? (Y/N)") ; 
        String s = getIns () ; 
        while (!((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))) 
        {
            System.out.println ("try again") ; 
            s = getIns () ; 
        } 
        if (s.equals ("y") || s.equals ("Y") ) 
        z = true ; 
    } 
    return a ; 
}

the error i get is:

Risk.java:416: cannot find symbol
symbol  : variable a
location: class Risk
        return a ; 
               ^

Why did i get this error? It seems that a is clearly defined in the line String[] a = assignTeams () ; and if anything is used by the line String[] a = assignTeams () ; and if anything is used by the line printOrder (a) ;` it seems to me that if the symbol a really couldn't be found then the compiler should blow up there and not at the return statment.

(also the method assignTeams returns an array of Strings.)

The variable a is defined within the scope of the while (CPU==false) loop -- it's not accessible outside of that while loop's scope. You need to define a inside the outermost scope (the same scope that the return statement is in). You can either keep the assignment where it is, or if it's possible, do it at the same time as definition.

public static String[] runTeams (String CPUcolor) 
{  
    boolean z = false ; 
    String[] a = null; // define a here, assign to null value
    boolean CPU = false ; 
    while (z == false) 
    { 
        while (CPU==false) 
        {
            a = assignTeams () ; // assign a here
            printOrder (a) ;

            for (int i = 1; i<a.length; i++) 
            { 
                if (a[i].equals(CPUcolor)) CPU = true ;
            }
            if (CPU==false) 
            {
                System.out.println ("ERROR YOU NEED TO INCLUDE THE COLOR OF THE CPU IN THE TURN ORDER") ; 
            }
        }
        System.out.println ("is this turn order correct? (Y/N)") ; 
        String s = getIns () ; 
        while (!((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))) 
        {
            System.out.println ("try again") ; 
            s = getIns () ; 
        } 
        if (s.equals ("y") || s.equals ("Y") ) 
        z = true ; 
    } 
    return a ; 
}

JLS 14.4.2 Scope of Local Variable Declarations :

The scope of a local variable declaration in a block is the rest of the block in which the declaration appears, starting with its own initializer and including any further declarators to the right in the local variable declaration statement.

JLS 14.2 Blocks

A block is a sequence of statements, local class declarations and local variable declaration statements within braces.

The way you declared and initialized a , it's actually a local variable to the while (CPU==false) block, and it goes immediately out of scope at the end of that block.

Similar questions


It should also be pointed out that the habit of explicitly comparing with boolean constants is a bad one. That is, instead of:

while (z == false)
while (CPU==false) 
if (CPU==false) 

You should've used:

while (!z)
while (!CPU) 
if (!CPU) 

You can also rename the variables for better readability ( isXXX is usually a good descriptive name), but the least you can do is to always do the following rewrites:

b == true  ---> b
b == false ---> !b
b != true  ---> !b
b != false ---> b

As a last tip, learning a bit of regex doesn't hurt. That is, instead of:

((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))

You can simply write the following:

s.matches("y|Y|n|N")

Learning resources

These kind of problems are obviously solved with IDEs like Eclipse. Which IDE are you using?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM