Pogreška pri kompilaciji "Ne mogu pronaći simbol"

1. Pregled

U ovom uputstvu pregledat ćemo što su pogreške kompilacije, a zatim ćemo posebno objasniti što je pogreška "ne mogu pronaći simbol" i kako je uzrokovana.

2. Sastavljanje pogrešaka u vremenu

Tijekom kompilacije, kompajler analizira i provjerava kôd za brojne stvari; referentni tipovi, odljevi tipova i deklaracije metoda da nabrojimo nekoliko. Ovaj dio postupka kompilacije važan je jer ćemo tijekom ove faze dobiti pogrešku kompilacije.

U osnovi postoje tri vrste pogrešaka tijekom prevođenja:

  • Možemo imati sintaksne pogreške. Jedna od najčešćih pogrešaka koje svaki programer može napraviti je zaboraviti staviti tačku i zarez na kraj izjave; neki drugi zaboravljaju na uvoz, ne podudaraju se zagrade ili izostavljaju povratnu izjavu
  • Dalje, postojepogreške provjere tipa. Ovo je postupak provjere sigurnosti tipa u našem kodu. Ovom provjerom osiguravamo postojanje dosljednih vrsta izraza. Na primjer, ako definiramo varijablu tipa int, nikada ne bismo trebali dodijeliti dvostruko ili Niz vrijednost za njega
  • U međuvremenu postoji mogućnost da se kompajler sruši. To je vrlo rijetko, ali može se dogoditi. U ovom je slučaju dobro znati da naš kôd možda ne predstavlja problem, već da je to vanjski problem

3. Pogreška "ne mogu pronaći simbol"

Pogreška "ne mogu pronaći simbol" pojavljuje se uglavnom kada pokušavamo koristiti varijablu koja nije definirana ili deklarirana u našem programu.

Kada se naš kod kompajlira, prevoditelj mora provjeriti sve identifikatore koje imamo. Greška"Ne mogu pronaći simbol" znači da jesmopozivajući se na nešto za što sastavljač ne zna.

3.1. Što može uzrokovati "ne mogu naći simbol" Pogreška?

Doista je samo jedan uzrok: Prevoditelj nije mogao pronaći definiciju varijable na koju se pokušavamo pozivati.

Ali, mnogo je razloga zašto se to događa. Da bismo lakše razumjeli zašto, podsjetimo se od čega se sastoji Java kôd.

Naš Java izvorni kod sastoji se od:

  • Ključne riječi: istina, laž, klasa, dok
  • Književnost: brojevi i tekst
  • Operatori i drugi ne-alfanumerički tokeni: -, /, +, =, {
  • Identifikatori: glavni, Čitač, ja, toStringitd.
  • Komentari i razmaci

4. Pogrešno pravopis

Najčešća su pitanja povezana s pravopisom. Ako se prisjetimo da su svi Java identifikatori osjetljivi na velika i mala slova, možemo vidjeti da:

  • StringBiulder
  • stringBuilder
  • String_Builder

svi bi to bili različiti načini pogrešnog pozivanja na StringBuilder razred.

5. Instanca Opseg

Ova pogreška također može nastati kada se koristi nešto što je deklarirano izvan opsega klase.

Na primjer, recimo da imamo Članak razred koji poziva a generirajId metoda:

članak javne klase {private int length; privatni dugi ID; javni članak (int length) {this.length = length; this.id = generirajId (); }}

Ali, proglašavamo generirajId metoda u zasebnom razredu:

javna klasa IdGenerator {public long generiraj () {Random random = new Random (); vrati random.nextInt (); }}

Ovom postavkom kompajler će dati pogrešku "ne mogu pronaći simbol" generirajId u retku 7 Članak isječak. Razlog je taj što sintaksa retka 7 implicira da generirajId metoda je deklarirana u Članak.

Kao i u svim zrelim jezicima, postoji više načina za rješavanje ovog problema. Ali, jedan od načina bio bi konstruiranje IdGenerator u Članak klase, a zatim pozovite metodu:

članak javne klase {private int length; privatni dugi ID; javni članak (int length) {this.length = length; this.id = novi IdGenerator (). generiraj Id (); }}

6. Nedefinirane varijable

Ponekad zaboravimo deklarirati varijablu. Kao što možemo vidjeti iz isječka u nastavku, pokušavamo manipulirati varijablom koju nismo deklarirali, u ovom slučaju, tekst:

članak javne klase {private int length; // ... javna praznina setText (String newText) {this.text = newText; // tekstualna varijabla nikad nije definirana}}

Taj problem rješavamo deklariranjem varijable tekst tipa Niz:

članak javne klase {private int length; privatni tekst niza; // ... javna praznina setText (String newText) {this.text = newText; }}

7. Promjenjivi opseg

Kad je deklaracija varijable izvan opsega u trenutku kada smo je pokušali koristiti, uzrokovat će pogrešku tijekom kompilacije. To se obično događa kada radimo s petljama.

Varijablama unutar petlje nije moguće pristupiti izvan petlje:

public boolean findLetterB (Tekst niza) {for (int i = 0; i <text.length (); i ++) {Character character = text.charAt (i); if (String.valueOf (character) .equals ("b")) {return true; } return false; } if (znak == "a") {// <- pogreška! ...}}

The ako Izjava bi trebala ići unutar za petlju ako trebamo više ispitati likove:

public boolean findLetterB (Tekst niza) {for (int i = 0; i <text.length (); i ++) {Character character = text.charAt (i); if (String.valueOf (character) .equals ("b")) {return true; } else if (String.valueOf (character) .equals ("a")) {...} return false; }}

8. Neispravna upotreba metoda ili polja

Pogreška "ne mogu pronaći simbol" pojavit će se i ako kao metodu koristimo polje ili obrnuto:

članak javne klase {private int length; privatni dugi ID; privatni tekstovi s popisa; javni članak (int length) {this.length = length; } // geteri i postavljači}

Sada, ako se pokušamo pozvati na Članke tekstova polje kao da je metoda:

Članak članak = novi članak (300); Popis tekstova = article.texts ();

tada bismo vidjeli pogrešku.

To je zato što kompajler traži metodu koja se zove tekstova, kojeg nema.

Zapravo, postoji getter metodu koju umjesto toga možemo koristiti:

Članak članak = novi članak (300); Popis tekstova = article.getTexts ();

Pogrešno operiranje niza, a ne elementa niza, također je problem:

za (Tekst niza: tekstovi) {String firstLetter = text.charAt (0); // to bi trebao biti text.charAt (0)}

Pa tako i zaboravljanje novi ključna riječ kao u:

Niz s = String (); // trebao bi biti 'novi String ()'

9. Uvoz paketa i klase

Drugi je problem zaboraviti na uvoz klase ili paketa. Na primjer, pomoću a Popis objekt bez uvoza java.util.Popis:

// nedostaje izjava o uvozu: // import java.util.List public class Article {private int length; privatni dugi ID; privatni tekstovi s popisa; <- pogreška! javni članak (int length) {this.length = length; }}

Ovaj se kod ne bi kompajlirao, jer program ne zna što Popis je.

10. Pogrešan uvoz

Uvoz pogrešne vrste zbog dovršenja IDE-a ili automatske korekcije također je čest problem.

Razmislite o situaciji kada želimo koristiti datume u Javi. Puno smo puta mogli uvesti pogrešan podatak Datum klase, koja ne pruža metode i funkcionalnosti kao druge klase datuma koje bi nam mogle trebati:

Datum datuma = novi datum (); int godina, mjesec, dan;

Da biste dobili godinu, mjesec ili dan za java.util.Datum, također moramo uvoziti Kalendar klase i odatle izvući podatke.

Jednostavno prizivanje getDate () iz java.util.Datum neće raditi:

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

Umjesto toga koristimo Kalendar objekt:

... Kalendar cal = Calendar.getInstance (TimeZone.getTimeZone ("Europa / Pariz")); cal.setTime (datum); year = cal.get (Calendar.YEAR); mjesec = kal.get (Kalendar.MJESEC); day = cal.get (Calendar.DAY_OF_MONTH);

Međutim, ako smo uvezli LocalDate klase, ne bi nam trebao dodatni kôd koji nam daje potrebne informacije:

... LocalDate localDate = date.toInstant (). AtZone (ZoneId.systemDefault ()). ToLocalDate (); year = localDate.getYear (); month = localDate.getMonthValue (); dan = localDate.getDayOfMonth ();

11. Zaključak

Prevoditelji rade na fiksnom skupu pravila koja su specifična za jezik. Ako se kod ne pridržava ovih pravila, kompajler ne može izvršiti postupak pretvorbe što rezultira pogreškom kompilacije. Kad se suočimo s pogreškom kompilacije "Ne mogu pronaći simbol", ključ je identificirati uzrok.

Iz poruke o pogrešci možemo pronaći redak koda u kojem se pogreška javlja i koji je element pogrešan. Poznavanje najčešćih problema koji uzrokuju ovu pogrešku učinit će njezino rješavanje vrlo jednostavnim i brzim.