Rumah  >  Soal Jawab  >  teks badan

Apakah yang dimaksudkan dengan ralat "simbol tidak ditemui" atau "tidak dapat menyelesaikan simbol"?

Sila terangkan perkara berikut tentang ralat "simbol tidak ditemui", "tidak dapat menyelesaikan simbol" atau "simbol tidak ditemui" (dalam Java):

Soalan ini bertujuan untuk menyediakan Soal Jawab yang komprehensif tentang ralat kompilasi biasa di Jawa ini.

P粉106711425P粉106711425397 hari yang lalu1260

membalas semua(2)saya akan balas

  • P粉203792468

    P粉2037924682023-10-10 12:40:19

    Jika anda terlupa new anda juga akan mendapat ralat ini:

    String s = String();

    Perbandingan

    String s = new String();

    Oleh kerana panggilan tanpa kata kunci new 关键字的调用将尝试查找不带参数的名为 String akan cuba mencari kaedah (asli) bernama String yang tidak mengambil parameter - dan tandatangan kaedah itu mungkin tidak ditentukan.

    balas
    0
  • P粉946437474

    P粉9464374742023-10-10 11:07:06

    0. Adakah terdapat perbezaan antara ralat ini?

    Tidak benar. "Simbol tidak ditemui", "Tidak dapat menyelesaikan simbol" dan "Simbol tidak ditemui" semuanya bermaksud perkara yang sama. (Penyusun Java yang berbeza ditulis oleh orang yang berbeza, dan orang yang berbeza menggunakan perkataan yang berbeza untuk mengatakan perkara yang sama.)

    1. Apakah maksud ralat "simbol tidak ditemui"?

    Pertama sekali, ini adalah ralat penyusunan1. Ini bermakna terdapat masalah dalam kod sumber Java anda, atau terdapat masalah dengan cara anda menyusunnya.

    Kod sumber Java anda mengandungi perkara berikut:

    • Kata kunci: Contohnya classwhile dll.
    • Teks: Seperti truefalse42'X'“嗨妈妈!”.
    • pengendali dan token bukan abjad lain: cth. +={
    • Pengecam: Contohnya
    • dll. ReaderitoStringprocessEquibalancedElephants
    • Komen dan ruang.
    Ralat "Simbol tidak ditemui" berkaitan dengan pengecam. Semasa menyusun kod, pengkompil perlu memikirkan maksud setiap pengecam dalam kod.

    Ralat "Simbol tidak ditemui" bermakna pengkompil tidak dapat melaksanakan operasi ini. Kod anda nampaknya merujuk sesuatu yang tidak difahami oleh pengkompil.

    2. Apakah yang menyebabkan ralat "simbol tidak ditemui"?

    Sebagai tempahan pertama, hanya ada satu sebab. Pengkompil mencari di mana-mana tempat pengecam harus ditakrifkan, tetapi tidak menemui definisi. Ini boleh disebabkan oleh pelbagai sebab. Yang biasa termasuk yang berikut:

    • Untuk pengecam umum:

        Mungkin nama anda dieja dengan betul; Java tidak boleh dan tidak cuba untuk mengimbangi kesilapan ejaan atau kesilapan tipografi.
      • StringBiulder 而不是 StringBuilderMungkin anda salah faham; Semua pengecam Java adalah sensitif huruf besar-besaran.
      • Mungkin anda menggunakan garis bawah dengan salah; iaitu stringBuilder 而不是 StringBuilder berbeza. (Jika anda berpegang kepada peraturan gaya Java, anda akan mengelakkan kesilapan ini...)
      • Mungkin anda cuba menggunakan sesuatu yang diisytiharkan "di tempat lain"; iaitu dalam konteks yang berbeza daripada yang anda secara tersirat memberitahu pengkompil untuk melihat. (Kelas berbeza? Skop berbeza? Pakej berbeza? Pangkalan kod berbeza?) mystringmy_string
      Untuk pengecam yang harus merujuk pembolehubah:
    • Mungkin anda terlupa untuk mengisytiharkan pembolehubah.

        Mungkin pengisytiharan pembolehubah telah di luar skop apabila anda cuba menggunakannya. (lihat contoh di bawah)
      Untuk pengecam yang sepatutnya merupakan kaedah atau nama medan:
    • Mungkin anda cuba merujuk kaedah atau medan yang diwarisi yang tidak diisytiharkan dalam kelas atau antara muka ibu bapa/nenek moyang.
      • Mungkin anda cuba merujuk kaedah atau medan yang tidak wujud (iaitu belum diisytiharkan) dalam jenis yang anda gunakan sebagai contoh
      • 2

        . "rope".push()

      • Mungkin anda cuba menggunakan kaedah sebagai medan atau sebaliknya "rope".lengthsomeArray.length().

      • Mungkin anda tersilap memanipulasi tatasusunan dan bukannya elemen tatasusunan sebagai contoh

        String strings[] = ...
            if (strings.charAt(3)) { ... }
            // maybe that should be 'strings[0].charAt(3)'
    • Untuk pengecam yang sepatutnya nama kelas:

      • Mungkin anda terlupa mengimport kelas.

      • Mungkin anda menggunakan import "asterisk" tetapi kelas tidak ditentukan dalam mana-mana pakej yang anda import.

      • Mungkin anda terlupa satu new seperti ini:

        String s = String();  // should be 'new String()'
      • Mungkin anda cuba mengimport atau sebaliknya menggunakan kelas yang telah diisytiharkan dalam pakej lalai iaitu di mana kelas tanpa pernyataan package berada.

        Petua: Buka bungkusan. Anda hanya perlu menggunakan pakej lalai untuk aplikasi mudah yang terdiri daripada satu kelas...atau sekurang-kurangnya satu fail sumber Java.

    • Untuk kes di mana jenis atau kejadian nampaknya tidak mempunyai ahli (seperti kaedah atau medan) yang anda harapkan ada:

      • Mungkin anda telah mengisytiharkan kelas bersarang atau parameter generik, menyembunyikanjenis yang anda ingin gunakan.
      • Mungkin anda menyembunyikan pembolehubah statik atau pembolehubah contoh.
      • Mungkin anda mengimport jenis yang salah; cth. java.awt.List 而不是 java.util.List
      • Mungkin anda menggunakan (mengkompil) versi API yang salah.
      • Mungkin anda terlupa untuk menghantar objek ke subkelas yang sesuai.
      • Mungkin anda telah mengisytiharkan
      • jenis pembolehubah sebagai supertype ahli yang anda cari.
    Soalan selalunya gabungan di atas. Contohnya, mungkin anda "bintang" mengimport kelas dalam

    . java.io.*,然后尝试使用 Files 类...它位于 java.nio而不是java.io。或者,也许您打算编写 File ...,它是 java.io


    Contoh berikut menggambarkan cara skop pembolehubah yang salah boleh membawa kepada ralat "simbol tidak ditemui":

    List strings = ...
    
    for (int i = 0; i < strings.size(); i++) {
        if (strings.get(i).equalsIgnoreCase("fnord")) {
            break;
        }
    }
    if (i < strings.size()) {
        ...
    }

    Ini akan memberikan ralat "simbol tidak ditemui" untuk i dalam pernyataan if. Walaupun kami mengisytiharkan i lebih awal, pengisytiharan itu hanyalah untuk
    pernyataan dan isinya

    skopif 语句中为 i 提供“找不到符号”错误。尽管我们之前声明了 i,但该声明仅for 语句及其主体范围if 语句中对 i 的引用看不到 i. Rujukan kepada i dalam pernyataan if tidak dapat melihat pengisytiharan i. Ia

    di luar skop

    . if 语句移至循环内部,或在循环开始之前声明 i

    (Pembetulan yang sesuai di sini mungkin untuk
    .)

    Berikut ialah contoh mengelirukan apabila kesilapan menaip menyebabkan ralat "simbol tidak ditemui" yang kelihatan tidak dapat dijelaskan: println 调用中给您一个编译错误,指出无法找到 i

    for (int i = 0; i < 100; i++); {
        System.out.println("i is " + i);
    }

    Ini akan berada dalam 🎜. Tetapi (saya dengar anda berkata) saya telah mengumumkannya! 🎜

    Masalahnya ialah { 之前的分号 ( ; )。 Java 语言语法将该上下文中的分号定义为空语句。然后,空语句将成为 for badan gelung. Jadi kod ini sebenarnya bermaksud:

    for (int i = 0; i < 100; i++); 
    
    // The previous and following are separate statements!!
    
    {
        System.out.println("i is " + i);
    }

    { ... } 块不是 for 循环的主体,因此之前在 i 中的声明code>for Kenyataan adalah di luar skop blok.


    Ini adalah satu lagi contoh ralat "simbol tidak ditemui" yang disebabkan oleh kesilapan menaip.

    int tmp = ...
    int res = tmp(a + b);

    Walaupun pengisytiharan sebelumnya, tmp(...) 表达式中的 tmp 是错误的。编译器将查找名为 tmp 的方法,但找不到。之前声明的 tmp berada dalam ruang nama pembolehubah, bukan ruang nama kaedah.

    Dalam contoh yang saya temui, pengaturcara sebenarnya meninggalkan operator. Apa yang dia ingin tulis pada asalnya ialah:

    int res = tmp * (a + b);

    Ada satu lagi sebab mengapa pengkompil mungkin tidak menemui simbol jika menyusun daripada baris arahan. Anda mungkin terlupa untuk menyusun atau menyusun semula beberapa kelas lain. Sebagai contoh, jika anda mempunyai kelas FooBar,其中 Foo 使用 Bar。如果您从未编译过 Bar 并且运行 javac Foo.java,您很容易发现编译器找不到符号 Bar 。简单的答案是将 FooBar 一起编译;例如javac Foo.java Bar.javajavac *.java. Atau lebih baik masih menggunakan alat binaan Java seperti Ant, Maven, Gradle, dll.

    Ada beberapa sebab lain yang lebih kabur... yang akan saya bincangkan di bawah.

    3. Bagaimana untuk membetulkan ralat ini?

    Secara umumnya, anda perlu mengetahui apa yang menyebabkan ralat kompilasi.

    • Lihat baris dalam fail yang ditunjukkan oleh mesej ralat kompilasi.
    • Tentukan simbol yang dimaksudkan oleh mesej ralat.
    • Ketahui mengapa pengkompil mengatakan simbol tidak dapat ditemui;

    Kemudian anda berfikir tentang perkara yang sepatutnya dinyatakan oleh kod anda. Akhir sekali, anda menentukan pembetulan yang perlu dibuat pada kod sumber untuk mencapai apa yang anda mahukan.

    Sila ambil perhatian bahawa tidak setiap "pembetulan" adalah betul. Pertimbangkan ini:

    for (int i = 1; i < 10; i++) {
        for (j = 1; j < 10; j++) {
            ...
        }
    }

    Andaikan pengkompil menggesa "simbol tidak ditemui" untuk j. Terdapat banyak cara saya boleh "membetulkan" perkara ini:

    • Saya boleh meletakkan dalaman for 更改为 for (int j = 1; j < 10; j++) - mungkin betul.
    • Saya boleh menambah pernyataan untuk for 循环或外部 for 循环之前添加一个 for j
    • sebelum gelung for dalam atau gelung for luar
    • - mungkin betul. for 循环中将 j 更改为 i
    • Saya boleh menukar
    • kepada i dalam gelung for dalam - mungkin salah!
    Tunggu.

    Intinya, anda

    perlu 🎜 memahami perkara yang cuba dilakukan oleh kod anda untuk mencari pembetulan yang betul. 🎜

    4. Sebab tidak diketahui

    Dalam beberapa kes berikut, "simbol tidak ditemui" kelihatan membingungkan... sehingga anda melihat lebih dekat.

    1. Kebergantungan salah: Jika anda menggunakan IDE atau alat binaan yang menguruskan laluan binaan dan kebergantungan projek, anda mungkin telah membuat kesilapan dengan kebergantungan seperti meninggalkan kebergantungan atau memilih Versi yang salah. Jika anda menggunakan alat binaan (Ant, Maven, Gradle, dll.), semak fail binaan projek anda. Jika anda menggunakan IDE, semak konfigurasi laluan binaan projek anda.

    2. Simbol 'var' tidak ditemui: Anda mungkin cuba menggunakan versi lama untuk menyusun menggunakan inferens jenis pembolehubah tempatan (iaitu var 声明)的源代码编译器或更旧的 --source 级别。 var telah diperkenalkan dalam Java 10. Semak versi JDK anda dan bina fail juga ( Jika ini berlaku dalam IDE) Tetapan IDE

      .
    3. Anda tidak menyusun/menghimpun semula: Kadangkala, pengaturcara Java baharu tidak memahami cara rantai alat Java berfungsi, atau tidak melaksanakan "proses binaan" yang boleh diulang cth . Dalam kes ini, pengaturcara mungkin akhirnya mengejar ralat hantu yang sebenarnya disebabkan oleh, sebagai contoh, tidak menyusun semula kod dengan betul.

      Contoh lain ialah apabila anda menggunakan (Java 9+) java SomeClass.java 编译和运行类时。如果该类依赖于您尚未编译(或重新编译)的另一个类,则您可能会收到涉及第二类的“无法解析符号”错误。其他源文件不会自动编译。 java Mod "Kompil dan Jalankan" arahan baharu tidak sesuai untuk menjalankan program dengan berbilang fail kod sumber.

    4. Isu Binaan Awal: Binaan awal mungkin gagal menyebabkan fail JAR tiada kelas. Jika anda menggunakan alat binaan, anda biasanya akan melihat kegagalan sedemikian. Walau bagaimanapun, jika anda memperoleh fail JAR daripada orang lain, anda bergantung pada mereka membina dengan betul dan menyedari ralat. Jika anda mengesyaki perkara ini, gunakan tar -tvf untuk menyenaraikan kandungan fail JAR yang disyaki.

    5. Isu IDE: Orang ramai telah melaporkan situasi di mana IDE mereka menjadi keliru dan pengkompil dalam IDE tidak dapat mencari kelas yang wujud... atau sebaliknya.

      • Ini mungkin berlaku jika IDE dikonfigurasikan dengan versi JDK yang salah.

      • Ini mungkin berlaku jika cache IDE tidak segerak dengan sistem fail. Terdapat beberapa cara khusus IDE untuk menyelesaikan masalah ini.

      • Ini mungkin pepijat IDE. Contohnya, @Joel Costigliola menerangkan senario di mana Eclipse gagal mengendalikan pokok "ujian" Maven dengan betul: Lihat jawapan ini . (Nampaknya pepijat ini telah dibetulkan lama dahulu.)

    6. Masalah Android: Apabila anda memprogramkan untuk Android, jika anda menjumpai fail kelas yang berkaitan dengan R 相关的“找不到符号”错误,请注意 R 符号由 context.xml 文件定义。检查您的 context.xml 文件是否正确且位于正确的位置,以及是否已生成/编译相应的 R. Ambil perhatian bahawa simbol Java adalah sensitif huruf besar-besaran, jadi id XML yang sepadan juga sensitif huruf besar-besaran.

      Ralat simbol lain pada Android mungkin disebabkan oleh sebab yang dinyatakan sebelum ini seperti kebergantungan yang hilang atau salah, nama pakej yang salah, kaedah atau medan yang tidak wujud dalam versi API tertentu, ralat ejaan/menaip, dsb.

    7. Sembunyikan Kelas Sistem: Saya pernah melihat kes di mana pengkompil mengadu bahawa substring adalah simbol yang tidak diketahui, seperti ini

      String s = ...
      String s1 = s.substring(1);

      Ternyata pengaturcara mencipta versi String mereka sendiri dan versi kelasnya tidak mentakrifkan kaedah String 版本,并且他的类版本没有定义 substring 方法。我见过人们使用 SystemScanner. Saya telah melihat orang menggunakan System, Scanner dan kelas lain untuk melakukan ini.

      Pengajaran: Jangan tentukan kelas anda sendiri dengan nama yang sama dengan kelas perpustakaan awam!

      Masalah ini juga boleh diselesaikan dengan menggunakan nama yang layak sepenuhnya. Contohnya, dalam contoh di atas, seorang pengaturcara boleh menulis:

      java.lang.String s = ...
      java.lang.String s1 = s.substring(1);
    8. Homoglyphs: Jika anda menggunakan pengekodan UTF-8 untuk fail sumber anda, anda mungkin akan mendapat pengecam yang kelihatan sama tetapi sebenarnya berbeza kerana ia mengandungi homoglyph. Sila lihat halaman ini untuk maklumat lanjut.

      Anda boleh mengelakkan perkara ini dengan mengehadkan diri anda kepada ASCII atau Latin-1 sebagai pengekodan fail sumber, dan menggunakan Java uxxxx untuk melepaskan aksara lain.


    1 - Jika anda melakukan melihat ini dalam pengecualian masa jalan atau mesej ralat, anda telah mengkonfigurasikan IDE anda untuk menjalankan kod dengan ralat penyusunan, atau aplikasi anda sedang dibina dan disusun pada kod masa jalan.
    2 - Tiga prinsip asas kejuruteraan awam: air tidak mengalir ke tempat yang lebih tinggi, papan menjadi lebih kuat apabila mereka berhadapan antara satu sama lain, dan anda tidak boleh menolak tali.

    balas
    0
  • Batalbalas