50 個 Java 開發常見錯誤及規避技巧 (Part 1)

2021-03-02 動力節點Java學院

在開發 Java 軟體時可能會遇到許多類型的錯誤,但大多數可以避免。 我們列舉了 50 個最常見的 Java 軟體錯誤,其中包含代碼示例和教程,以幫助您解決常見的編碼問題。

如果您正在使用 .NET,您還應該查看我們的 50 個最常見的 .NET 軟體錯誤指南,以及如何避免這些錯誤。 如果您當前的挑戰與 Java 相關,請繼續閱讀以了解最常見的問題及其解決方法。

編譯器錯誤


編譯器錯誤消息在Java軟體代碼在編譯器執行時產生。需要重點記住的是,一個編譯器可能為一個錯誤拋出多個錯誤消息。所以修復第一個錯誤並重編譯,就能修復很多的問題。


1. 「… 可預料的」


當編碼出現遺漏時,就會發生這類錯誤。可能是缺失了一個括號或者分號。

private static double volume(String solidom, double alturam, double areaBasem, double raiom) { double vol;    if (solidom.equalsIgnoreCase("esfera"){        vol=(4.0/3)*Math.pi*Math.pow(raiom,3);    }    else {        if (solidom.equalsIgnoreCase("cilindro") {            vol=Math.pi*Math.pow(raiom,2)*alturam;        }        else {            vol=(1.0/3)*Math.pi*Math.pow(raiom,2)*alturam;        }    }    return vol;}

這種錯誤消息常常不會準確的定位到錯誤發生的位置。為了找到錯誤,建議:


2.「未封閉的 String 表達式」


「未封閉的 String 表達式」錯誤消息發生在 Sting 表達式結束時沒有引號標記,錯誤消息將在發生錯誤的同一行提示出來。一個 String 表達式在源碼中是一個值。

 public abstract class NFLPlayersReference {    private static Runningback[] nflplayersreference;    private static Quarterback[] players;    private static WideReceiver[] nflplayers;    public static void main(String args[]){    Runningback r = new Runningback("Thomlinsion");    Quarterback q = new Quarterback("Tom Brady");    WideReceiver w = new WideReceiver("Steve Smith");    NFLPlayersReference[] NFLPlayersReference;        Run();        nflplayersreference[0] = r;        players[1] = q;        nflplayers[2] = w;            for ( int i = 0; i < nflplayersreference.length; i++ ) {            System.out.println("My name is " + " nflplayersreference[i].getName());            nflplayersreference[i].run();            nflplayersreference[i].run();            nflplayersreference[i].run();            System.out.println("NFL offensive threats have great running abilities!");        }    }    private static void Run() {        System.out.println("Not yet implemented");    }     }

通常情況下,錯誤發生在:

String 表達式結束時沒有使用引號標記。這種錯誤只要在 String 表達式結束是使用引號就能簡單的改正

String 表達式超過一行時。長的 String 表達式可以被拆分成多個表達式,然後用 "+" 連接起來。

引號是 String 表達式中的元素又沒有使用下劃線「\」進行轉義。

3. 「非法的表達式開頭」 

出現「非法表達式開頭」錯誤的原因有很多。但它最終歸類於一個不太有用的錯誤消息之一。有些開發者說這是由糟糕的代碼造成的。

通常,創建表達式是用於生成新值或為變量賦值。編譯器期望找到一個表達式,但找不到它,因為語法不符合預期。 在下面這些語句中可以找到此錯誤。

}        public void newShape(String shape) {        switch (shape) {            case "Line":                Shape line = new Line(startX, startY, endX, endY);            shapes.add(line);            break;                case "Oval":            Shape oval = new Oval(startX, startY, endX, endY);            shapes.add(oval);            break;            case "Rectangle":            Shape rectangle = new Rectangle(startX, startY, endX, endY);            shapes.add(rectangle);            break;            default:            System.out.println("ERROR. Check logic.");        }        }    }     }

4. 「找不到符號」 


這是一個非常常見的問題,因為 Java 中的所有標識符都需要在使用之前進行聲明。 當編譯代碼時,編譯器並不理解標識符的含義。

在你遇到「找不到符號」消息時可能有很多種原因:

標識符聲明時的拼寫可能與代碼中使用時的拼寫不同。

該變量從未被聲明。

該變量使用的位置與其聲明的作用域不同。

類並未被導入。

5. 「公共類 XXX 應該在文件中出現」


「公共類 XXX 應該在文件中出現」這個消息出現在類XXX和Java程序文件名不一致時。原始碼只有在類名和 Java 文件名一樣時才會被編譯:

package javaapplication3;    public class Robot {          int xlocation;          int ylocation;          String name;          static int ccount = 0;          public Robot(int xxlocation, int yylocation, String nname) {              xlocation = xxlocation;              ylocation = yylocation;              name = nname;              ccount++;                 }   }  public class JavaApplication1 {     public static void main(String[] args) {          robot firstRobot = new Robot(34,51,"yossi");          System.out.println("numebr of robots is now " + Robot.ccount);      }  }

要修復這種情況:

6. 「不兼容類型」 


「不兼容的類型」是在賦值語句中嘗試將變量與類型表達式匹配時觸發的邏輯錯誤。通常是在代碼嘗試將文本字符寫入到整數中時出現,反之亦然。 這不是 Java 語法錯誤。 

test.java:78: error: incompatible typesreturn stringBuilder.toString();                             ^required: intfound:    String1 error

當編譯器給出「不兼容的類型」消息時,確實沒有一個簡單的修複方案:

有可以轉換類型的函數。

開發人員可能需要按照代碼的預期修改之。

7. 「無效的方法聲明;需求返回類型」

此錯誤表示方法籤名中沒有明確說明方法的返回類型。

public class Circle{    private double radius;    public CircleR(double r)    {        radius = r;    }    public diameter()    {       double d = radius * 2;       return d;    }}

有幾種方式會觸發「無效的方法聲明; 需求返回類型「錯誤:

8. 「類 Y 中的方法 X 不能應用於給定類型」


此錯誤消息是 Java 中最有用的錯誤消息之一。 它解釋了方法籤名是如何調用錯誤參數的。

RandomNumbers.java:9: error: method generateNumbers in class RandomNumbers cannot be applied to given types;generateNumbers();required: int[]found:generateNumbers();reason: actual and formal argument lists differ in length

方法在被調用時期望獲取在方法聲明中定義的某些參數。 檢查方法聲明、謹慎調用方法,以確保聲明和調用的參數是兼容的。

9. 「缺少返回語句」


當一個方法缺少返回語句時,會發生「缺少返回語句」錯誤。 每一個有返回值的方法(非 void 類型)必須有一句字面上的語句用以返回返回值,以便在方法外調用該值。

public String[] OpenFile() throws IOException {    Map<String, Double> map = new HashMap();    FileReader fr = new FileReader("money.txt");    BufferedReader br = new BufferedReader(fr);    try{        while (br.ready()){            String str = br.readLine();            String[] list = str.split(" ");            System.out.println(list);                       }    }   catch (IOException e){        System.err.println("Error - IOException!");    }}

下面列舉了一些編譯器拋出「缺少返回語句」的消息的原因:


10. 「精度可能丟失」


當將超過一個變量可以保存的信息分配給該變量時,會發生「精度可能丟失」問題。如果發生這種情況,超出的信息將會被扔掉。如果這樣做沒問題,那麼代碼需要將變量顯式地聲明為新類型。

下面情況會發生「精度可能丟失」錯誤:

將一個實數賦值給一個整型變量。

將一個雙精度浮點數賦值給一個整型變量。

Java 中原始數據類型解析展示了數據是怎麼表示的。

11. 「解析時到達文件末尾」


這個錯誤信息經常發生在 Java 程序缺少「}」符號時。通常在代碼末加上「}」符號能很快解決這個問題。

public class mod_MyMod extends BaseModpublic String Version(){     return "1.2_02";}public void AddRecipes(CraftingManager recipes){   recipes.addRecipe(new ItemStack(Item.diamond), new Object[] {      "#", Character.valueOf('#'), Block.dirt   });}

上述代碼的運行結果是下列錯誤:

java:11: reached end of file while parsing }

代碼編寫工具和適當的代碼縮進可以更容易地找到這些不對的大括號。


12. 「語句不可達」


「語句不可達」發生在當語句被放在一個不會被執行的位置時候。通常是在 break 語句或 return 語句後面。

for(;;){   break;   ... }int i=1;if(i==1)  ...else  ... 

通常簡單地移動 return 語句就能解決這個錯誤。

13. 「變量 x 可能未被初始化」


這個問題發生在當方法內局部變量在聲明時沒有被初始化的時候。當一個變量未被初始化但是出現在 if 語句中的時候會發生該錯誤。

int x;if (condition) {    x = 5;}System.out.println(x); 

14. 「操作符 ... 不能應用於 x」

這個情況發生於當操作符應用於沒有定義其使用方法的類型上。

operator < cannot be applied to java.lang.Object,java.lang.Object

當 Java 代碼嘗試使用 string 類型進行數學計算時會經常出現這個問題。為了解決它,string 需要被轉化為 integer 或 float。

15. 「不能轉換的類型」


「不能轉換的類型」錯誤發生在 Java 代碼嘗試進行非法轉換的時候。

TypeInvocationConversionTest.java:12: inconvertible typesfound   : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>required: java.util.ArrayList<java.lang.Class<?>>    lessRestrictiveClassList = (ArrayList<Class<?>>) classList;                                                     ^

例如,boolean 不能轉換為 int。

16. 「缺少返回值」

當返回語句返回一個錯誤的類型時,你就會收到「缺少返回值」消息。例如下列代碼:

public class SavingsAcc2 {    private double balance;    private double interest;    public SavingsAcc2() {        balance = 0.0;        interest = 6.17;    }    public SavingsAcc2(double initBalance, double interested) {        balance = initBalance;        interest = interested;    }    public SavingsAcc2 deposit(double amount) {        balance = balance + amount;        return;    }    public SavingsAcc2 withdraw(double amount) {        balance = balance - amount;        return;    }    public SavingsAcc2 addInterest(double interest) {        balance = balance * (interest / 100) + balance;        return;    }    public double getBalance() {        return balance;    }}

返回下列錯誤信息:

SavingsAcc2.java:29: missing return value return; ^ SavingsAcc2.java:35: missing return value return; ^ SavingsAcc2.java:41: missing return value return; ^ 3 errors

通常,那些返回語句沒有返回任何東西。

17. 「返回類型為 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;}

18. 「非靜態變量 ... 不能在靜態上下文中被引用」

當編譯器嘗試在一個靜態方法中訪問一個非靜態變量時會發生該錯誤 :

public class StaticTest {    private int count=0;    public static void main(String args[]) throws IOException {        count++;     }}

為了解決「非靜態變量 ... 不能在靜態上下文中被引用」的錯誤,有下述兩種方法:

在籤名中將變量聲明為靜態變量。

在靜態方法中創建一個非靜態對象的示例

19. 「非靜態方法 ... 不能在靜態上下文中被引用」

這個情況發生在 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>未初始化」的消息。 數組的長度是固定的,因此每個數組都需要按照實際長度進行初始化。

以下代碼是可以接受的:

AClass[] array = {object1, object2}

下面也是可以的:

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

但是這個不行:

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

請閱讀關於在 Java 軟體中如何初始化數組的討論。

接下來的內容


現在我們已經討論了編譯器錯誤,下次我們將深入討論各種可能出現的運行時異常,這些異常會浪費你一整天時間。 就像本部分,它們將包含代碼塊、解釋和相關連結,以幫助您儘快修復代碼。


補充能量,回顧閱讀:

程式設計師應勤工資真有這麼高?編劇你可別騙我!

程式設計師!或將是未來最吃香的職業?

你知道為什麼程序中的缺陷叫bug嗎?

一個十二年老程序猿的碎碎念
(最新)各大公司Java後端開發面試題總結

Java初學者的30個常見問題

文章來源:開源翻譯

相關焦點

  • 50個常見的 Java 錯誤及避免方法(第二部分)
    object1, object2};21.; System.out.println("Length: " + str.length()); char ch = str.charAt(50); }}和數組索引一樣,字符串索引從零開始。在索引字符串的時候,最後一個字符小於字符串的長度。
  • 50個常見的 Java 錯誤及避免方法(第三部分)
    (MessageUtil.java:28) at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:13) ... 10 more修復此錯誤我們需要更多的信息。在代碼中使用getCause()可以返回導致錯誤的異常。37.
  • 50個簡單流利的英語口語技巧 Part 1-10
    今天給大家分享的是50組如何提高你的英語口語水平的小技巧,先來1-10組,每個小技巧對我們的學習都很有幫助。50個簡單流利的英語口語技巧Part 1-1004:58來自大劉的英語世界# TIP 1be realistic about your English learning goals
  • [初級]Java開發人員最常犯的10個錯誤
    這個類雖然和java.util.ArrayList同名,但是並不是同一個類。java.util.Arrays.ArrayList類中實現了set(), get(), contains()等方法,但是並沒有定義向其中增加元素的方法。也就是說通過Arrays.asList()得到的ArrayList的大小是固定的。
  • Javaweb開發學習路線及Java三大框架分享
    學習目標:Java程式設計師1: 熟悉jdk,jvm,eclipse,安裝於配置jdk2:熟悉並掌握java的基礎語法,類,抽象類,接口,內部類等概念3: java核心編程,如輸入輸出流,多線程,集合,XML,正則表達式等4:java
  • 雅思口語part 1的五個最佳技巧
    小編總結了下面這些口語備考常見問題,就做不到張口就來,極大的影響了口語的流利度。中國烤鴨的通病就是開口少,所以在考場上口語比其他三科更難提分,就連在練習中該如何更好地改善答案,大多烤鴨可能也沒個明確的方向。今天為大家分享雅思口語考試part 1的五個最佳技巧,這些技巧都是來自雅思前考官Keith在網上教授的數千門雅思考試課程中總結出來的技巧。
  • 50個簡單流利的英語口語技巧 Part 41-50
    50個簡單流利的英語口語技巧 Part 1-1050個簡單流利的英語口語技巧 Part 11-2050個簡單流利的英語口語技巧 Part 21-30# TIP 41# TIP 43Engage in English activities參加英語活動Taking part in activities that involve the use of spoken English can make
  • Java程式設計師的良藥:應用程式的開發技巧
    【IT168 技術】 假如你是一名Java開發者,正在開發和維護包含2000個類並使用了很多框架的應用程式。你要如何理解這些代碼呢?在典型的Java企業項目小組中,大部分能夠幫你的高級工程師看起來都很忙,文檔也很少。你需要儘快交付成果,並向項目組證明自己的能力。你會如何處理這種狀況呢?
  • 寫作學術論文英文摘要如何規避常見錯誤
    很多作者在學術論文英文摘要寫作中常犯格式、詞法、句法等方面的錯誤,雖不是影響判斷論文是否符合所投期刊用稿標準的關鍵因素,但倘若能規避,將給作者發文、編輯用稿減少了不必要的麻煩及時間,而規避這錯誤,對於作者而言,也是可為與可行的。
  • 讀完《Effective Java》後,總結了 50 條開發技巧
    1、考慮用靜態工廠方法替代構造函數例子:Integer.valueOf(「1」)、Boolean.valueOf(「true」)等。優勢:下面針對三個優勢進行一些解讀。可讀性高new Point(x,y)和Point.at(x,y)、Point.origin()。構造函數只能看出兩個參數,不知其意,後者更易理解。
  • Java編程中常見的異常
    數組的初始化是對數組分配需要的空間,而初始化後的數組,其中的元素並沒有實例化,依然是空的,所以還需要對每個元素都進行初始化(如果要調用的話)2.java.lang.classnotfoundexception    這個異常是很多原本在jb等開發環境中開發的程式設計師,把jb下的程序包放在wtk下編譯經常出現的問題,異常的解釋是
  • Java項目中常見的異常產生原因及處理辦法
    使用throw語句可以隨時拋出這種異常對象:throw new ArithmeticException(…);二、異常發生的原因有很多,通常包含以下幾大類:三、幾種常見的異常及其產生原因1、java.lang.NullPointerException(空指針異常)原因:這個異常大家肯定都經常遇到,異常的解釋是"程序遇上了空指針",即,調用了未經初始化的對象或者是不存在的對象
  • java大數據之Hadoop開發環境
    JAVA和大數據是什麼關係大數據框架的編寫支持很多開發語言,但是Java在大數據開發方面有很大的優勢,目前流行的大數據Hadoop
  • Java開發必會的Linux命令
    作為一個Java開發人員,有些常用的Linux命令必須掌握。
  • JavaScript 開發中常見錯誤排查
    ,這對我們來說無疑是一種挫折,在不知如何著手解決錯誤的時,只能反覆地檢查自己的代碼,看看是不是有什麼奇怪的地方,有時就算停在了錯誤地方也往往不知是什麼意思,會因此花費大量的時間。本文就來介紹在 Chrome 開發者工具中常見的錯誤反饋及排除技巧,讓你不再為了滿屏幕的紅字感到挫折,更能從中學習如何快速搜尋錯誤代碼。
  • Java、JavaScript、PHP、Python是什麼?能開發什麼?
    它是一種被標準化的交流技巧,用來向計算機發出指令。一種計算機語言讓程式設計師能夠準確地定義計算機所需要使用的數據,並精確地定義在不同情況下所應當採取的行動。如果我們想用電腦或者讓一個應用按照你的指令工作,這時就需要用程式語言來把指令翻譯成電腦能懂的,從而去完成指令。
  • 大學生學Java編程開發真的很值得
    2021-01-03 16:32:07 來源: IT培訓 舉報   java
  • 各地java開發工程師平均工資 北京高級java開發工程師工資2萬多
    java開發工程師一般分為幾個等級,初級開發工程師(時間:0~1 年),中級開發工程師(時間:1~13年),高級開發工程師(時間:5年以上)。據國內某網站樣本調查顯示各地java開發工程師平均工資,數據僅供參考。北京java開發工程平均工資為17920人民幣,近1年 35417 份樣本。
  • Java 8的五大開發技巧
    在Java 9發布之前,我們來分享一些Java 8開發技巧,本文翻譯自JetBrains高級開發主管Trisha Geed的Java 8 Top
  • Java初學者的30個常見問題
    官方微博:動力節點文章來源:極思維 本文回答了30個JAVA入門級初學者的常見問題。