50個常見的 Java 錯誤及避免方法(第二部分)

2017-09-21    分類:JAVA開發、程式設計開發、首頁精華0人評論發表於2017-09-21

本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃

接上文50個常見的 Java 錯誤及避免方法(第一部分)

17.“Cannot Return a Value From Method Whose Result Type Is Void”

當一個void方法嘗試返回值時,就會發生此Java錯誤,例如在以下示例中:

public static void move()
{
    System.out.println("What do you want to do?");
    Scanner scan = new Scanner(System.in);
    int userMove = scan.nextInt();
    return userMove;
}
public static void usersMove(String playerName, int gesture)
{
    int userMove = move();
    if (userMove == -1)
    {
        break;
    }

通常,這可以通過更改方法簽名匹配返回語句中的型別來修正錯誤。在這種情況下,void的例項可以改為int:

public static int move()
{
    System.out.println("What do you want to do?");
    Scanner scan = new Scanner(System.in);
    int userMove = scan.nextInt();
    return userMove;
}

閱讀關於如何修復“Cannot Return a Value From Method Whose Result Type Is Void”錯誤的討論。(@StackOverflow)

18.“Non-Static Variable … Cannot Be Referenced From a Static Context”

當編譯器嘗試從靜態方法(@javinpaul)訪問非靜態變數時,就會發生此錯誤:

public class StaticTest {
    private int count=0;
    public static void main(String args[]) throws IOException {
        count++; //compiler error: non-static variable count cannot be referenced from a static context
    }
}

要修復“Non-Static Variable … Cannot Be Referenced From a Static Context”錯誤,可以做這兩件事:

  • 在簽名中宣告此變數為靜態。
  • 在靜態方法中寫程式碼建立非靜態物件的例項。

閱讀此介紹靜態和非靜態變數之間區別的教程。(@sitesbay)

19.“Non-Static Method … Cannot Be Referenced From a Static Context”

此問題發生在Java程式碼嘗試在非靜態類中呼叫非靜態方法的情況下。 例如,以下程式碼:

class Sample
{
   private int age;
   public void setAge(int a)
   {
      age=a;
   }
   public int getAge()
   {
      return age;
   }
   public static void main(String args[])
   {
       System.out.println("Age is:"+ getAge());
   }
}

將返回錯誤:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Cannot make a static reference to the non-static method getAge() from the type Sample

從靜態方法中呼叫非靜態方法就是宣告呼叫非靜態方法的類的例項。

閱讀此關於非靜態方法和靜態方法之間區別的闡述

20.“(array) <X> Not Initialized”

當陣列被宣告但未初始化時,你將得到“(array) <X> Not Initialized”的訊息。陣列的長度是固定的,因此每個陣列都需要以所需的長度進行初始化。

以下程式碼就可以接受:

AClass[] array = {object1, object2}

即:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

而非:

AClass[] array;
...
array = {object1, object2};

閱讀此關於如何在Java軟體中初始化陣列的討論。(@StackOverflow)

21.“ArrayIndexOutOfBoundsException”

這是在程式碼嘗試訪問不在值內的陣列索引時發生的執行時錯誤訊息。以下程式碼將觸發此異常:

String[] name = {
    "tom",
    "dick",
    "harry"
};
for (int i = 0; i <= name.length; i++) {
    System.out.print(name[i] + '\n');
}

這是另一個例子(@DukeU)

int[] list = new int[5];
list[5] = 33; // illegal index, maximum index is 4

陣列索引從零開始,結束於小於陣列長度的那一個。通常,當定義陣列索引的限制時,通過使用“<”而不是“<=”來修復。

檢視此關於索引如何觸發“ArrayIndexOutOfBoundsException”Java軟體錯誤訊息的例子。(@StackOverflow)

22.“StringIndexOutOfBoundsException”

當程式碼嘗試訪問不在字串範圍內的字串的一部分時,就會發生這種問題。通常,這發生在程式碼嘗試建立字串的子字串,且長度與引數設定不符之時。下面是一個例子(@javacodegeeks):

public class StringCharAtExample {
    public static void main(String[] args) {
        String str = "Java Code Geeks!";
        System.out.println("Length: " + str.length());
        //The following statement throws an exception, because
        //the request index is invalid.
        char ch = str.charAt(50);
    }
}

和陣列索引一樣,字串索引從零開始。在索引字串的時候,最後一個字元小於字串的長度。 “StringIndexOutOfBoundsException”Java軟體錯誤訊息通常意味著索引正在嘗試訪問沒有包含的字元。

這裡有一個說明“StringIndexOutOfBoundsException”如何發生和修復的例子。(@StackOverflow)

23.“NullPointerException”

當程式嘗試使用沒有賦值的物件引用時,就會出現“NullPointerException”異常。(@geeksforgeeks)

// A Java program to demonstrate that invoking a method
// on null causes NullPointerException
import java.io.*;
class GFG
{
    public static void main (String[] args)
    {
        // Initializing String variable with null value
        String ptr = null;
        // Checking if ptr.equals null or works fine.
        try
        {
            // This line of code throws NullPointerException
            // because ptr is null
            if (ptr.equals("gfg"))
                System.out.print("Same");
            else
                System.out.print("Not Same");
        }
        catch(NullPointerException e)
        {
            System.out.print("NullPointerException Caught");
        }
    }
}

Java程式經常在以下情況下出現異常:

  • 語句引用一個空值的物件。
  • 嘗試訪問一個已定義但未分配引用的類。

這裡有一個開發人員遇到“NullPointerException”以及如何處理它的討論。(@StackOverflow)

24.“NoClassDefFoundError”

當直譯器找不到包含主方法的類的檔案時,將發生“NoClassDefFoundError”異常。來自DZone的示例(@DZone):

如果你編譯此程式:

class A
{
  // some code
}
public class B
{
    public static void main(String[] args)
    {
        A a = new A();
    }
}

生成兩個.class檔案:A.class和B.class。刪除A.class檔案並執行B.class檔案,你將得到NoClassDefFoundError的訊息:

Exception in thread "main" java.lang.NoClassDefFoundError: A
at MainClass.main(MainClass.java:10)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

發生這種情況的原因有:

  • 檔案不在正確的目錄內。
  • 類的名稱必須與檔案的名稱相同(不包括副檔名)。名稱分大小寫。

閱讀此關於執行Java軟體時為什麼發生“NoClassDefFoundError”的討論。(@StackOverflow)

25.“NoSuchMethodFoundError”

當Java軟體嘗試呼叫類的方法並且該方法不再有定義時,將發生此錯誤訊息(@myUND):

Error: Could not find or load main class wiki.java

當宣告中有錯字時,通常會出現“NoSuchMethodFoundError”Java軟體錯誤。

閱讀此教程以瞭解如何避免“NoSuchMethodFoundError”的錯誤訊息。(@javacodegeeks)

26.“NoSuchProviderException”

當請求的安全提供程式不可用時,會發生“NoSuchProviderException”異常(@alvinalexander):

javax.mail.NoSuchProviderException

當試圖找到為什麼發生“NoSuchProviderException”時,請檢查:

  • JRE配置。
  • 配置中設定的Java home。
  • 使用哪個Java環境。
  • 安全提供程式條目。

閱讀關於在執行Java軟體時會導致“NoSuchProviderException”原因的討論。(@StackOverflow)

27. AccessControlException

AccessControlException表示所請求訪問的系統資源,如檔案系統或網路是被拒絕的,如本例中的JBossDeveloper(@jbossdeveloper):

ERROR Could not register mbeans java.security.
AccessControlException: WFSM000001: Permission check failed (permission "("javax.management.MBeanPermission" "org.apache.logging.log4j.core.jmx.LoggerContextAdmin#-
[org.apache.logging.log4j2:type=51634f]" "registerMBean")" in code source "(vfs:/C:/wildfly-10.0.0.Final/standalone/deployments/mySampleSecurityApp.war/WEB-INF/lib/log4j-core-2.5.
jar )" of "null")

閱讀這篇關於解決方法的討論,以解決“AccessControlException”錯誤。(@github)

28.“ArrayStoreException”

當Java陣列中轉換元素的規則被破壞時,就會發生“ArrayStoreException”異常。對於放到陣列中的內容一定要非常小心。(@Roedyg)例如,來自JavaScan.com的這個例子說明此程式(@java_scan):

/* ............... START ............... */
 public class JavaArrayStoreException {
     public static void main(String...args) {
         Object[] val = new Integer[4];
         val[0] = 5.8;
     }
 }
 /* ............... END ............... */

可以產生以下輸出:

Exception in thread "main" java.lang.ArrayStoreException: java.lang.Double
at ExceptionHandling.JavaArrayStoreException.main(JavaArrayStoreException.java:7)

當陣列被初始化時,我們需要宣告允許進入陣列的物件的種類。 每個陣列元素都需要成為相同型別的物件。

閱讀此關於如何解決“ArrayStoreException”的討論。(@StackOverflow)

29.“Bad Magic Number”

此Java軟體錯誤訊息意味著網路上的類定義檔案可能出錯了。 以下是來自The Server Side的示例(@TSS_dotcom):

Java(TM) Plug-in: Version 1.3.1_01
Using JRE version 1.3.1_01 Java HotSpot(TM) Client VM
User home directory = C:\Documents and Settings\Ankur
Proxy Configuration: Manual Configuration
Proxy: 192.168.11.6:80
java.lang.ClassFormatError: SalesCalculatorAppletBeanInfo (Bad magic number)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at sun.applet.AppletClassLoader.findClass(Unknown Source)
at sun.plugin.security.PluginClassLoader.access$201(Unknown Source)
at sun.plugin.security.PluginClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.security.PluginClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.applet.AppletClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.beans.Introspector.instantiate(Unknown Source)
at java.beans.Introspector.findInformant(Unknown Source)
at java.beans.Introspector.(Unknown Source)
at java.beans.Introspector.getBeanInfo(Unknown Source)
at sun.beans.ole.OleBeanInfo.(Unknown Source)
at sun.beans.ole.StubInformation.getStub(Unknown Source)
at sun.plugin.ocx.TypeLibManager$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.ocx.TypeLibManager.getTypeLib(Unknown Source)
at sun.plugin.ocx.TypeLibManager.getTypeLib(Unknown Source)
at sun.plugin.ocx.ActiveXAppletViewer.statusNotification(Native Method)
at sun.plugin.ocx.ActiveXAppletViewer.notifyStatus(Unknown Source)
at sun.plugin.ocx.ActiveXAppletViewer.showAppletStatus(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

“bad magic number”錯誤訊息可能發生在以下情況下:

  • 類檔案的前四個位元組不是十六進位制數字CAFEBABE。
  • 類檔案以ASCII模式而不是以二進位制模式上傳。
  • Java程式在編譯之前執行。

閱讀此關於如何找到“bad magic number”異常原因的討論。(@coderanch)

30.“Broken Pipe”

此錯誤訊息是指來自檔案或網路套接字的資料流已停止工作或從另一端關閉(@ExpertsExchange)。

Exception in thread "main" java.net.SocketException: Broken pipe
      at java.net.SocketOutputStream.socketWrite0(Native Method)
      at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
      at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
      at java.io.DataOutputStream.write

出現broken pipe的原因通常有:

  • 耗盡磁碟暫存空間。
  • RAM可能被堵塞。
  • 資料流可能已損壞。
  • 讀取管道的過程可能已經關閉。

閱讀此關於Java錯誤“broken pipe”的討論。(@StackOverflow)

第二部分完,敬請關注第三部分的內容。

譯文連結:http://www.codeceo.com/article/50-java-errors-part-2.html
英文原文:50 Common Java Errors and How to Avoid Them (Part 2)
翻譯作者:碼農網 – 小峰
轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]

相關文章