java - What does a "Cannot find symbol" compilation error mean? -
please explain following "cannot find symbol" error:
- what error mean?
- what things can cause error?
- how programmer go fixing error?
this question designed comprehensive question "cannot find symbol" compilation errors in java.
1. "cannot find symbol" error mean?
firstly, compilation error1. means either there problem in java source code, or there problem in way compiling it.
your java source code consists of following things:
- keywords:
true
,false
,class
,while
, , on. - literals:
42
,'x'
,"hi mum!"
. - operators , other non-alphanumeric tokens:
+
,=
,{
, , on. - identifiers:
reader
,i
,tostring
,processequibalancedelephants
, , on. - comments , whitespace.
a "cannot find symbol" error identifiers. when code compiled, compiler needs work out each , every identifier in code means.
a "cannot find symbol" error means compiler cannot this. code appears referring compiler doesn't understand.
2. can cause "cannot find symbol" error?
as first order, there 1 cause. compiler looked in of places identifier should defined, , couldn't find definition. caused number of things. common ones follows:
- for identifiers in general:
- perhaps spelled name incorrectly; i.e.
stringbiulder
instead ofstringbuilder
. java cannot , not attempt compensate bad spelling or typing errors. - perhaps got case wrong; i.e.
stringbuilder
instead ofstringbuilder
. java identifiers case sensitive. - perhaps used underscores inappropriately; i.e.
mystring
,my_string
different. (if stick java style rules, largely protected mistake ...) - perhaps trying use declared "somewhere else"; i.e. in different context have implicitly told compiler look. (a different class? different scope? different package? different code-base?)
- perhaps spelled name incorrectly; i.e.
- for identifiers should refer variables:
- perhaps forgot declare variable.
- perhaps variable declaration out of scope @ point tried use it. (see example below)
- for identifiers should method names:
- perhaps trying refer inherited method wasn't declared in parent / ancestor classes or interfaces.
for identifiers should class names:
- perhaps forgot import class.
- perhaps used "star" imports, class isn't defined in of packages imported.
perhaps forgot
new
in:string s = string(); // should 'new string()'
for cases type or instance doesn't appear have member expecting have:
- perhaps have declared nested class or generic parameter shadows type meaning use.
- perhaps shadowing static or instance variable.
- perhaps imported wrong type; e.g. due ide completion or auto-correction.
- perhaps using (compiling against) wrong version of api.
- perhaps forgot cast object appropriate subclass.
the problem combination of above. example, maybe "star" imported java.io.*
, tried use files
class ... in java.nio
not java.io
. or maybe meant write file
... is class in java.io
.
here example of how incorrect variable scoping can lead "cannot find symbol" error:
for (int = 0; < strings.size(); i++) { if (strings.get(i).equalsignorecase("fnoord")) { break; } } if (i < strings.size()) { ... }
this give "cannot find symbol" error i
in if
statement. though declared i
, declaration in scope for
statement , body. reference i
in if
statement cannot see declaration of i
. out of scope.
(an appropriate correction here might move if
statement inside loop, or declare i
before start of loop.)
here example causes puzzlement typo leads seemingly inexplicable "cannot find symbol" error:
for (int = 0; < 100; i++); { system.out.println("i " + i); }
this give compilation error in println
call saying i
cannot found. (i hear say) did declare it!
the problem sneaky semicolon before {
. java language defines empty statement. code means this:
for (int = 0; < 100; i++); { system.out.println("i " + i); }
the { ... }
block not body of for
loop, declaration of i
not in scope in the block.
here example of "cannot find symbol" error caused typo.
int tmp = ... int res = tmp(a + b);
despite previous declaration, tmp
in tmp(...)
expression erroneous. compiler method called tmp
, , won't find one. declared tmp
in namespace variables, not namespace methods.
in example came across, programmer had left out operator. meant write this:
int res = tmp * (a + b);
there reason why compiler might not find symbol if compiling command line. might have forgotten compile or recompile other class. example, if have classes foo
, bar
foo
uses bar
. if have never compiled bar
, run javac foo.java
, liable find compiler can't find symbol bar
. simple answer foo
, bar
together; e.g. javac foo.java bar.java
or javac *.java
. or better still use java build tool; e.g. ant, maven, gradle , on.
there other more obscure causes ... deal below.
3. how fix these errors ?
generally speaking, start out figuring out caused compilation error.
- look @ line in file indicated compilation error message.
- identify symbol error message talking about.
- figure out why compiler saying cannot find symbol; see above!
then think code supposed saying. work out correction need make source code want.
note not every "correction" correct. consider this:
for (int = 1; < 10; i++) { (j = 1; j < 10; j++) { ... } }
suppose compiler says "cannot find symbol" j
. there many ways "fix" that:
- i change inner
for
for (int j = 1; j < 10; j++)
- correct. - i add declaration
j
before innerfor
loop, or outerfor
loop - possibly correct. - i change
j
i
in innerfor
loop - wrong! - and on.
the point need understand code trying in order find right fix.
4. obscure causes
here couple of cases "cannot find symbol" seemingly inexplicable ... until closer.
you looking @ wrong source code: happens new java programmers don't understand how java tool chain works, or haven't implemented repeatable "build process"; e.g. using ide, ant, maven, gradle , on. in such situation, programmer can end chasing tail looking illusory error actually caused not recompiling code properly, , ...
ide issues: people have reported cases ide gets confused , compiler in ide cannot find class exists ... or reverse situation.
this can happen if ide's caches out of sync file system. there ide specific ways fix that.
this ide bug. instance @joel costigliola describes scenario eclipse not handle maven "test" tree correctly: see answer.
redefining system classes: i've seen cases compiler complains
substring
unknown symbol in followingstring s = ... string s1 = s.substring(1);
it turned out programmer had created own version of
string
, version of class didn't definesubstring
methods.lesson: don't define own classes same names common library classes!
homoglyphs: if use utf-8 encoding source files, possible have identifiers look same, in fact different because contain homoglyphs. see this page more information.
you can avoid restricting ascii or latin-1 source file encoding, , using java
\uxxxx
escapes other characters.
1 - if, perchance, do see in runtime exception or error message, either have configured ide run code compilation errors, or application generating , compiling code .. @ runtime.
Comments
Post a Comment