Kompileringsfejlen "Kan ikke finde symbolet"

1. Oversigt

I denne vejledning gennemgår vi, hvad kompileringsfejl er, og derefter specifikt forklares, hvad “ikke kan finde symbol” -fejlen er, og hvordan den er forårsaget.

2. Kompilér tidsfejl

Under kompilering analyserer og verificerer compileren koden for adskillige ting; referencetyper, type cast og metodedeklarationer for at nævne nogle få. Denne del af kompileringsprocessen er vigtig, da vi i denne fase får en kompileringsfejl.

Dybest set er der tre typer kompileringsfejl:

  • Vi kan have syntaksfejl. En af de mest almindelige fejl, som enhver programmør kan begå, er at glemme at sætte semikolonet i slutningen af ​​udsagnet; nogle andre glemmer import, stemmer ikke overens med parenteser eller udelader returopgørelsen
  • Dernæst er dertypekontrolfejl. Dette er en proces til kontrol af typesikkerhed i vores kode. Med denne kontrol sørger vi for, at vi har ensartede typer udtryk. For eksempel, hvis vi definerer en variabel af typen int, vi skal aldrig tildele en dobbelt eller Snor værdi for det
  • I mellemtiden er der en mulighed for, at compileren går ned. Dette er meget sjældent, men det kan ske. I dette tilfælde er det godt at vide, at vores kode muligvis ikke er et problem, men at det snarere er et eksternt problem

3. Fejlen “kan ikke finde symbolet”

Fejlen "kan ikke finde symbol" kommer hovedsageligt op, når vi prøver at bruge en variabel, der ikke er defineret eller deklareret i vores program.

Når vores kode kompileres, skal compileren kontrollere alle identifikatorer, vi har. Fejlen"Kan ikke finde symbol" betyder, at vi erder henviser til noget, som compileren ikke kender til.

3.1. Hvad kan forårsage “Kan ikke finde symbol” Fejl?

Der er virkelig kun én årsag: Compileren kunne ikke finde definitionen af ​​en variabel, som vi prøver at henvise til.

Men der er mange grunde til, at dette sker. For at hjælpe os med at forstå hvorfor, lad os minde os selv om, hvad Java-kode består af.

Vores Java-kildekode består af:

  • Nøgleord: sandt, falsk, klasse, mens
  • Bogstaver: tal og tekst
  • Operatører og andre ikke-alfanumeriske tokens: -, /, +, =, {
  • Identifikatorer: vigtigste, Læser, jeg, toString, etc.
  • Kommentarer og mellemrum

4. Stavefejl

De mest almindelige problemer er alle staverelaterede. Hvis vi husker, at alle Java-identifikatorer er store og små bogstaver, kan vi se, at:

  • StringBiulder
  • stringBuilder
  • String_Builder

alle ville være forskellige måder at forkert henvise til StringBuilder klasse.

5. Instansomfang

Denne fejl kan også skyldes, når du bruger noget, der blev erklæret uden for klassen.

Lad os for eksempel sige, at vi har en Artikel klasse, der kalder en generereId metode:

offentlig klasse artikel {privat int længde; privat lang id; offentlig artikel (int længde) {this.length = længde; this.id = generereId (); }}

Men vi erklærer generereId metode i en separat klasse:

offentlig klasse IdGenerator {offentlig lang generereId () {Tilfældig tilfældig = ny tilfældig (); return random.nextInt (); }}

Med denne opsætning vil compileren give en “kan ikke finde symbol” -fejl for generereId på linje 7 i Artikel uddrag. Årsagen er, at syntaksen for linje 7 indebærer, at createId metoden er erklæret i Artikel.

Som på alle modne sprog er der mere end en måde at løse dette problem på. Men en måde ville være at konstruere IdGenerator i Artikel klasse og derefter kalde metoden:

offentlig klasse artikel {privat int længde; privat lang id; offentlig artikel (int længde) {this.length = længde; this.id = ny IdGenerator (). generereId (); }}

6. Udefinerede variabler

Nogle gange glemmer vi at erklære variablen. Som vi kan se fra uddraget nedenfor, forsøger vi at manipulere den variabel, vi ikke har deklareret, i dette tilfælde tekst:

offentlig klasse artikel {privat int længde; // ... public void setText (String newText) {this.text = newText; // tekstvariabel blev aldrig defineret}}

Vi løser dette problem ved at erklære variablen tekst af typen Snor:

offentlig klasse artikel {privat int længde; privat strengtekst; // ... public void setText (String newText) {this.text = newText; }}

7. Variabelt anvendelsesområde

Når en variabelerklæring er uden for anvendelsesområdet på det tidspunkt, hvor vi forsøgte at bruge den, vil det forårsage en fejl under kompilering. Dette sker typisk, når vi arbejder med sløjfer.

Variabler inde i sløjfen er ikke tilgængelige uden for sløjfen:

offentlig boolsk findLetterB (strengtekst) {for (int i = 0; i <text.length (); i ++) {Character character = text.charAt (i); if (String.valueOf (character) .equals ("b")) {return true; } returner falsk; } hvis (tegn == "a") {// <- fejl! ...}}

Det hvis erklæring skal gå inde i til løkke hvis vi har brug for at undersøge tegn mere:

offentlig boolsk findLetterB (strengtekst) {for (int i = 0; i <text.length (); i ++) {Character character = text.charAt (i); if (String.valueOf (character) .equals ("b")) {return true; } ellers hvis (String.valueOf (karakter) .equals ("a")) {...} returnerer false; }}

8. Ugyldig brug af metoder eller felter

Fejlen "kan ikke finde symbol" opstår også, hvis vi bruger et felt som en metode eller omvendt:

offentlig klasse artikel {privat int længde; privat lang id; private Listetekster; offentlig artikel (int længde) {this.length = længde; } // getters og setters}

Nu, hvis vi prøver at henvise til artiklen tekster felt som om det var en metode:

Artikelartikel = ny artikel (300); Listetekster = article.texts ();

så ville vi se fejlen.

Det er fordi compileren er på udkig efter en metode kaldet tekster, som der ikke er en.

Faktisk er der en getter metode, som vi kan bruge i stedet:

Artikelartikel = ny artikel (300); Listetekster = article.getTexts ();

Fejlagtigt at arbejde på et array i stedet for et array-element er også et problem:

for (Stringtekst: tekster) {String firstLetter = tekster.charAt (0); // det skal være text.charAt (0)}

Og det er også at glemme ny nøgleord som i:

Streng s = Streng (); // skal være 'ny streng ()'

9. Pakke- og klasseimport

Et andet problem er at glemme at importere klassen eller pakken. Brug f.eks. En Liste objekt uden at importere java.util.List:

// manglende importerklæring: // import java.util.List public class Article {private int length; privat lang id; private Listetekster; <- fejl! offentlig artikel (int længde) {this.length = længde; }}

Denne kode ville ikke kompilere, da programmet ikke ved hvad Liste er.

10. Forkert import

Import af den forkerte type på grund af færdiggørelse af IDE eller automatisk korrektion er også et almindeligt problem.

Tænk på situationen, når vi vil bruge datoer i Java. Mange gange kunne vi importere en forkert Dato klasse, som ikke indeholder metoder og funktioner som andre dataklasser, som vi muligvis har brug for:

Dato dato = ny dato (); int år, måned, dag;

For at få året, måneden eller dagen for java.util.Date, skal vi også importere Kalender klasse og hente oplysningerne derfra.

Simpelthen påberåbt getDate () fra java.util.Date fungerer ikke:

... date.getDay (); date.getMonth (); date.getYear ();

I stedet bruger vi Kalender objekt:

... Kalender cal = Calendar.getInstance (TimeZone.getTimeZone ("Europa / Paris")); cal.setTime (dato); år = kal.get (Kalender.ÅR); måned = cal.get (Calendar.MONTH); dag = cal.get (Kalender.DAY_OF_MONTH);

Men hvis vi har importeret LocalDate klasse, behøver vi ikke yderligere kode, der giver os de oplysninger, vi har brug for:

... LocalDate localDate = date.toInstant (). AtZone (ZoneId.systemDefault ()). ToLocalDate (); år = localDate.getYear (); måned = localDate.getMonthValue (); dag = localDate.getDayOfMonth ();

11. Konklusion

Compilers arbejder på et fast sæt regler, der er sprogspecifikke. Hvis en kode ikke overholder disse regler, kan compileren ikke udføre en konverteringsproces, der resulterer i en kompileringsfejl. Når vi står over for kompileringsfejlen "Kan ikke finde symbol", er nøglen at identificere årsagen.

Fra fejlmeddelelsen kan vi finde kodelinjen, hvor fejlen opstår, og hvilket element der er forkert. At kende de mest almindelige problemer, der forårsager denne fejl, vil gøre det meget let og hurtigt at løse det.