Blog |

How to Resolve The Cannot Find Symbol Error in Java

How to Resolve The Cannot Find Symbol Error in Java
Table of Contents

When Java says "cannot find symbol," it's not being mysterious - it's being literal. Somewhere in your code, you've referenced something that doesn't exist in the compiler's world, even if it seems obvious to you. This disconnect happens because Java's compiler relies on symbol tables to track every identifier in your program, and when it can't locate what you're referencing, compilation stops dead in its tracks.

Understanding how Java's compiler thinks about symbols - and why it sometimes can't find them - is the key to quickly diagnosing and fixing these errors. Let's dive into what's happening under the hood and how to resolve it.

Introduction to Symbol Tables

Symbol tables are an important data structure created and maintained by compilers to store information associated with identifiers [1] in a given source code. Think of them as the compiler's address book - every variable, method, class, or interface you declare gets an entry that the compiler can look up later.

This information is entered into the symbol tables during lexical and syntax analysis and is used in the later phases of compilation. As the declarations of classes, interfaces, variables, and methods are processed, their identifiers are bound to corresponding entries in the symbol tables. When uses of these identifiers are encountered in the source code, the compiler looks them up in the symbol tables and relies on this information for things such as verifying that a variable has been declared, determining the scope of a variable, and verifying that an expression is semantically correct with type checking. Symbol tables are also used for code generation and optimization [2].

A simplified representation of a symbol table entry (or simply, a symbol) in Java has the following format: <symbol name (identifier), type, scope, [attributes]>. Given a global variable declaration like final double ratio; the corresponding symbol would then be <ratio, double, global, [final]>.

Cannot Find Symbol Error

As its name implies, the cannot find symbol error refers to a symbol which cannot be found. While there are multiple ways and reasons this can occur, they all boil down to the fact that the Java compiler is unable to find the symbol associated with a given identifier.

When this error occurs, the compiler provides helpful diagnostic information including:

  • “symbol”—the name and type of the referenced identifier; and
  • “location”—the specific class in which the identifier has been referenced.

Here's what a typical error message looks like:

MyClass.java:5: error: cannot find symbol
    System.out.println(message);
                       ^
  symbol:   variable message
  location: class MyClass

In this example, the compiler is telling you it can't find a variable called message on line 5 of the MyClass class. The caret (^) points to exactly where the problem occurs.

 

What Causes the Cannot Find Symbol Error

The most common triggers for the cannot find symbol compile-time error include:

  • Undeclared variables and methods - referencing something that was never defined
  • Out-of-scope references - trying to access variables outside their valid scope
  • Misspelled identifiers - typos in variable, method, or class names
  • Missing import statements - forgetting to import classes from other packages
  • Incorrect object creation - missing new keyword or other constructor issues

 

Cannot Find Symbol vs Symbol Not Found vs Cannot Resolve Symbol

As different Java compilers use slightly different terminology, the cannot find symbol error can also be found under the terms symbol not found and cannot resolve symbol. Despite the naming differences, they all indicate the same underlying problem.

 

Cannot Find Symbol Error Examples

Undeclared variable

Why this happens: Java requires explicit variable declaration before use. Unlike some languages that allow implicit declaration or hoisting, Java's compiler needs to see a variable's declaration before it can be referenced.

When the Java compiler encounters a use of an identifier which it cannot find in the symbol table, it raises the cannot find symbol error. Consequently, the most common occurrence of this error is when there is a reference to an undeclared variable. Unlike some other languages that don’t require explicit declaration of variables [3], or may allow declaring a variable after it has been referenced (via hoisting [4]), Java requires declaring a variable before it can be used or referenced in any way.

Fig. 1(a) shows how an undeclared variable, in this case the identifier average on line 9, results in two instances of the cannot find symbol error, at the positions where they appear in the code. Declaring this variable by specifying its data type (or, alternatively, inferring its type with the var keyword in Java 10+) resolves the issue (Fig. 1(b)).

(a)

1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;

public class UndeclaredVariable {
    public static void main(String... args) {
        int x = 6;
        int y = 10;
        int z = 32;

        average = (x + y + z) / 3.0; // average is not declared
        System.out.println(average);
    }
}
UndeclaredVariable.java:9: error: cannot find symbol
    average = (x + y + z) / 3.0;
    ^
  symbol:   variable average
  location: class UndeclaredVariable

UndeclaredVariable.java:10: error: cannot find symbol
    System.out.println(average);
                       ^
  symbol:   variable average
  location: class UndeclaredVariable
2 errors

(b)

1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;

public class UndeclaredVariable {
    public static void main(String... args) {
        int x = 6;
        int y = 10;
        int z = 32;

        double average = (x + y + z) / 3.0;
        System.out.println(average);
    }
}
16.0

Figure 1: Cannot find symbol for undeclared variable (a) error and (b) resolution

 

Out of scope variable

Why this happens: Variables in Java have limited scope - they're only accessible within the block where they're declared. When you try to access a variable outside its scope, the compiler can't find it in the symbol table for that location.

The example in Fig. 2(a) demonstrates this issue. The variable counter is declared within the for loop on line 11, making it only accessible inside that loop. When the code tries to access counter on lines 17 and 18 (outside the loop), the compiler throws the cannot find symbol error.

The fix is straightforward: declare the counter variable in a broader scope that encompasses all the places you need to use it, as shown in Fig. 2(b).

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package rollbar;

import java.util.Arrays;
import java.util.List;

public class OutOfScopeVariable {
    public static void main(String... args) {
        final List<String> strings = Arrays.asList("Hello", "World");
        final String searchFor = "World";

        for (int counter = 0; counter < strings.size(); counter++) {
            if (strings.get(counter).equals(searchFor)) {
                break;
            }
        }

        if (counter < strings.size()) {
            System.out.println("The word " + searchFor + " was found at index " +    counter);
        } else {
            System.out.println("The word " + searchFor + " wasn't found");
        }
    }
}
OutOfScopeVariable.java:17: error: cannot find symbol
    if (counter < strings.size()) {
        ^
  symbol:   variable counter
  location: class OutOfScopeVariable

OutOfScopeVariable.java:18: error: cannot find symbol
      System.out.println("The word " + searchFor + " was found at index " + counter);
                                                                            ^
  symbol:   variable counter
  location: class OutOfScopeVariable
2 errors

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package rollbar;

import java.util.Arrays;
import java.util.List;

public class OutOfScopeVariable {
    public static void main(String... args) {
        final List<String> strings = Arrays.asList("Hello", "World");
        final String searchFor = "World";
        int counter;

        for (counter = 0; counter < strings.size(); counter++) {
            if (strings.get(counter).equals(searchFor)) {
                break;
            }
        }

        if (counter < strings.size()) {
            System.out.println("The word " + searchFor + " was found at index " + counter);
        } else {
            System.out.println("The word " + searchFor + " wasn't found");
        }
    }
}
The word ‘World’ was found at index 1

Figure 2: Cannot find symbol for out-of-scope variable reference (a) error and (b) resolution

 

Misspelled method name

Why this happens: Java identifiers are case-sensitive, so fibonacci and Fibonacci are completely different to the compiler. Any variation in spelling, capitalization, or even subtle character differences will make the compiler unable to find the intended method.

This is often the most frustrating cause because the error isn't immediately obvious. In Fig. 3(a), the method fibonacci is defined with a lowercase 'f', but called with an uppercase 'F' on line 11. To the human eye, they look nearly identical, but to the Java compiler, Fibonacci(20) is a completely different method that doesn't exist.

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;

public class MisspelledMethodName {
    static int fibonacci(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

    public static void main(String... args) {
        int fib20 = Fibonacci(20); // Fibonacci ≠ fibonacci
        System.out.println(fib20);
    }
}
MisspelledMethodName.java:11: error: cannot find symbol
    int fib20 = Fibonacci(20);
                ^
  symbol:   method Fibonacci(int)
  location: class MisspelledMethodName

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;

public class MisspelledMethodName {
    static int fibonacci(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

    public static void main(String... args) {
        int fib20 = fibonacci(20);
        System.out.println(fib20);
    }
}
6765

Figure 3: Cannot find symbol for misspelled method name (a) error and (b) resolution

 

Missing import statement

Why this happens: Java organizes classes into packages to avoid naming conflicts and keep code organized. When you use a class from another package, you must explicitly import it so the compiler knows where to find it. Without the import, the compiler has no way to locate the class.

The code in Fig. 4(a) attempts to use the List class from java.util package without importing it. Even though Arrays.asList() is imported and returns a List, the compiler still needs to know what List means when you declare it as a type. Adding the missing import statement resolves the issue immediately.

(a)

1
2
3
4
5
6
7
8
9
10
11
package rollbar;

import java.util.Arrays;

public class MissingImportList {
    private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");

    public static void main(String... args) {
        System.out.println(CONSTANTS);
    }
}
MissingImportList.java:6: error: cannot find symbol
  private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");
                       ^
  symbol:   class List
  location: class MissingImportList

(b)

1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;

import java.util.Arrays;
import java.util.List;

public class MissingImportList {
    private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");

    public static void main(String... args) {
        System.out.println(CONSTANTS);
    }
}
[A, B, C]

Figure 4: Cannot find symbol for missing import (a) error and (b) resolution

 

Less common but tricky examples

While the examples above cover the majority of cases, some cannot find symbol errors hide in unexpected places. These subtle issues can be particularly frustrating because they're easy to overlook.

Accidental semicolon termination

In Fig. 5(a), notice the semicolon after the for loop declaration on line 6. This semicolon terminates the loop immediately, making the code block that follows separate from the loop. Since the variable i is only declared within the for loop scope, it's not accessible in the standalone block below.

(a)

1
2
3
4
5
6
7
8
9
10
package rollbar;

public class LoopScope {
public static void main(String... args) {
        int start = 1, end = 10;
        for (int i = start; i <= end; i++); {
            System.out.print(i == end ? i : i + ", ");
        }
    }
}
LoopScope.java:7: error: cannot find symbol
      System.out.print(i == end ? i : i + ", ");
                       ^
  symbol:   variable i
  location: class LoopScope

LoopScope.java:7: error: cannot find symbol
      System.out.print(i == end ? i : i + ", ");
                                  ^
  symbol:   variable i
  location: class LoopScope

LoopScope.java:7: error: cannot find symbol
      System.out.print(i == end ? i : i + ", ");
                                      ^
  symbol:   variable i
  location: class LoopScope
3 errors

(b)

1
2
3
4
5
6
7
8
9
10
package rollbar;

public class LoopScope {
    public static void main(String... args) {
        int start = 1, end = 10;
        for (int i = start; i <= end; i++) {
            System.out.print(i == end ? i : i + ", ");
        }
    }
}
1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Figure 5: Cannot find symbol for prematurely terminated for loop (a) error and (b) resolution

Missing new keyword

Fig. 6(a) shows what happens when you try to call a constructor without the new keyword. The compiler interprets String("Hello World!") as a method call rather than object creation, but no such method exists in the current class.

(a)

1
2
3
4
5
6
7
8
package rollbar;

public class ObjectCreation {
    public static void main(String... args) {
        String s = String("Hello World!");
        System.out.println(s);
    }
}
ObjectCreation.java:5: error: cannot find symbol
    String s = String("Hello World!");
               ^
  symbol:   method String(String)
  location: class ObjectCreation

(b)

1
2
3
4
5
6
7
8
package rollbar;

public class ObjectCreation {
    public static void main(String... args) {
        String s = new String("Hello World!");
        System.out.println(s);
    }
}
Hello World!

Figure 6: Cannot find symbol constructor call (a) error and (b) resolution

Other Potential Causes

Beyond the examples shown, cannot find symbol errors can also stem from:

  • using dependencies with old or incompatible versions;
  • forgetting to recompile a program;
  • building a project with an older JDK version;
  • redefining platform or library classes with the same name;
  • the use of homoglyphs in identifier construction that are difficult to tell apart;

 

Putting It All Together

The cannot find symbol error is Java's way of telling you that somewhere in your code, you're referencing something that doesn't exist in the compiler's symbol table. While this can be frustrating, the error message provides valuable clues about what's missing and where.

The fastest path to resolution:

  1. Check the error message for the specific symbol name and location
  2. Verify spelling and capitalization (remember, Java is case-sensitive)
  3. Ensure the variable or method is declared before use
  4. Check that you're within the correct scope
  5. Add any missing import statements

Most cannot find symbol errors fall into the common categories we've covered: undeclared variables, scope issues, typos, and missing imports. Once you understand these patterns, diagnosing and fixing these errors becomes second nature. The key is reading the compiler's error message carefully - it's usually telling you exactly what's wrong and where to look.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

 

References

[1] Rollbar, 2021. Handling the <Identifier> Expected Error in Java. Rollbar Editorial Team. [Online]. Available: https://rollbar.com/blog/how-to-handle-the-identifier-expected-error-in-java/. [Accessed Nov. 22, 2021].

[2] ITL Education Solutions Limited, Principles of Compiler Design (Express Learning), 1st ed. New Delhi: Pearson Education (India), 2012.

[3] Tutorialspoint.com, 2021. Python - Variable Types. [Online]. Available: https://www.tutorialspoint.com/python/python_variable_types.htm. [Accessed: Nov. 23, 2021].

[4] JavaScript Tutorial, 2021. JavaScript Hoisting Explained By Examples. [Online]. Available: https://www.javascripttutorial.net/javascript-hoisting/. [Accessed: Nov. 23, 2021]

Related Resources

"Rollbar allows us to go from alerting to impact analysis and resolution in a matter of minutes. Without it we would be flying blind."

Error Monitoring

Start continuously improving your code today.

Get Started Shape