20个常见 Java 错误以及如何避免它们
在开发 Java 软件时可能会遇到许多类型的错误,但大多数都是可以避免的。我们收集了 50 个最常见的 Java 软件错误,并附有代码示例和教程,可帮助您解决常见的编码问题。
编译器错误
当 Java 软件代码通过编译器运行时,会创建编译器错误消息。重要的是要记住,编译器可能会为一个错误抛出许多错误消息。所以修复第一个错误并重新编译。那可以解决很多问题。
1. “… Expected”
当代码中缺少某些内容时会发生此错误。这通常是由缺少分号或右括号造成的。
private static double volume(String solidom, double alturam, double areaBasem, double raiom) { double vol; if (域名lsIgnoreCase("esfera"){ vol=(4.0/3)*域名*域名(raiom,3); } else { if (域名lsIgnoreCase("cilindro") { vol=域名*域名(raiom,2)*alturam; } else { vol=(1.0/3)*域名*域名(raiom,2)*alturam; } } return vol; }
此错误消息通常不会指出问题的确切位置。要找到它:
确保所有左括号都有相应的右括号。
查看所指示的 Java 代码行之前的行。这个 Java 软件错误不会被编译器注意到,直到在代码中进一步出现。
有时,像左括号这样的字符一开始就不应该出现在 Java 代码中。所以开发者没有放置右括号来平衡括号。
2. “Unclosed String Literal”
“未闭合的字符串文字”错误消息是在字符串文字没有引号结束时创建的,并且该消息将与错误出现在同一行。
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 = new NFLPlayersReference [3]; nflplayersreference[0] = r; players[1] = q; nflplayers[2] = w; for ( int i = 0; i < 域名th; i++ ) { 域名tln("My name is " + " nflplayersreference[i].getName()); nflplayersreference[i].run(); nflplayersreference[i].run(); nflplayersreference[i].run(); 域名tln("NFL offensive threats have great running abilities!"); } } private static void Run() { 域名tln("Not yet implemented"); } }
通常,这种情况发生在:
字符串文字不以引号结尾。这很容易通过用所需的引号关闭字符串文字来更正。
字符串字面量超出一行。长字符串文字可以分解为多个文字并用加号 (“+”) 连接。
作为字符串文字一部分的引号不会使用反斜杠 (“\”) 进行转义。
3. “Illegal Start of an Expression”
出现“非法开始表达式”错误的原因有很多。它最终成为不太有用的错误消息之一。一些开发人员说这是由错误的代码引起的。
通常,创建表达式是为了产生新值或为变量赋值。编译器希望找到一个表达式,但由于语法与预期不匹配而无法找到它。
} // ADD IT HERE public void newShape(String shape) { switch (shape) { case "Line": Shape line = new Line(startX, startY, endX, endY); 域名(line); break; case "Oval": Shape oval = new Oval(startX, startY, endX, endY); 域名(oval); break; case "Rectangle": Shape rectangle = new Rectangle(startX, startY, endX, endY); 域名(rectangle); break; default: 域名tln("ERROR. Check logic."); } } } // REMOVE IT FROM HERE }
4. “Cannot Find Symbol”
这是一个非常常见的问题,因为 Java 中的所有标识符都需要在使用之前进行声明。在编译代码时,编译器不理解标识符的含义。
您可能会收到“找不到符号”消息的原因有很多:
声明时标识符的拼写可能与在代码中使用时的拼写不同。
该变量从未被声明。
该变量未在声明的同一范围内使用。
该类未导入。
5. “Public Class XXX Should Be in File”
当类 XXX 和 Java 程序文件名不匹配时,会出现“public class XXX should be in file”消息。只有在类和 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"); 域名tln("numebr of robots is now " + 域名nt); } }
要解决此问题:
命名类和文件相同。
确保两个名称的大小写一致。
6. “Incompatible Types”
“类型不兼容”是当赋值语句试图将变量与类型表达式配对时发生的逻辑错误。当代码试图将文本字符串放入整数时,通常会出现这种情况——反之亦然。这不是 Java 语法错误。
域名:78: error: incompatible types return 域名ring(); ^ required: int found: String 1 error
当编译器给出“不兼容的类型”消息时,确实没有一个简单的解决方法:
有可以转换类型的函数。
开发人员可能需要更改代码预期执行的操作。
7. “Invalid Method Declaration; Return Type Required”
此 Java 软件错误消息表示方法签名中未明确说明方法的返回类型。
public class Circle { private double radius; public CircleR(double r) { radius = r; } public diameter() { double d = radius * 2; return d; } }
有几种方法可以触发“无效方法声明;需要返回类型”错误:
忘记说明类型
如果该方法没有返回值,则需要在方法签名中将“void”声明为类型。
构造函数名称不需要说明类型。但是如果构造函数名称有错误,那么编译器会将构造函数视为没有声明类型的方法。
8. “Method <X> in Class <Y> Cannot Be Applied to Given Types”
此 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. “Missing Return Statement”
当方法没有 return 语句时,会出现“missing return statement”消息。每个返回值(非空类型)的方法都必须有一个真正返回该值的语句,以便可以在方法外调用它。
public String[] OpenFile() throws IOException { Map<String, Double> map = new HashMap(); FileReader fr = new FileReader("域名"); BufferedReader br = new BufferedReader(fr); try{ while (域名y()){ String str = 域名Line(); String[] list = 域名t(" "); 域名tln(list); } } catch (IOException e){ 域名tln("Error - IOException!"); } }
编译器抛出“missing return statement”消息的原因有几个:
return 语句只是被错误地省略了。
该方法未返回任何值,但未在方法签名中声明类型 void。
10. “Possible Loss of Precision”
当分配给变量的信息超过其所能容纳的信息时,就会发生“可能的精度损失”。如果发生这种情况,碎片将被扔掉。如果这没问题,那么代码需要将变量显式声明为新类型。
“可能的精度损失”错误通常发生在:
尝试将实数分配给具有整数数据类型的变量。
尝试为具有整数数据类型的变量分配双精度值。
11. “Reached End of File While Parsing”
当程序缺少右花括号(“}”)时,Java 中通常会出现此错误消息。有时可以通过将其放在代码末尾来快速修复。
public class mod_MyMod extends BaseMod public String Version() { return "域名"; } public void AddRecipes(CraftingManager recipes) { 域名ecipe(new ItemStack(域名ond), new Object[] { "#", 域名eOf('#'), 域名 }); }
上面的代码导致以下错误:
java:11: reached end of file while parsing }
编码实用程序和适当的代码缩进可以更容易地找到这些不平衡的大括号。
12. “Unreachable Statement”
当一个语句写在一个阻止它被执行的地方时,就会发生“Unreachable statement”。通常,这是在 break 或 return 语句之后。
for(;;){ break; ... // unreachable statement } int i=1; if(i==1) ... else ... // dead code
通常只需移动 return 语句即可修复错误。
13. “Variable <X> Might Not Have Been Initialized”
当在方法中声明的局部变量尚未初始化时,就会发生这种情况。当没有初始值的变量是 if 语句的一部分时,就会发生这种情况。
int x; if (condition) { x = 5; } 域名tln(x); // x may not have been initialized
14. “Operator ... Cannot be Applied to <X>”
当运算符用于不在其定义中的类型时,会出现此问题。
operator < cannot be applied to 域名ct,域名ct
当 Java 代码尝试在计算中使用类型字符串时,通常会发生这种情况。要修复它,需要将字符串转换为整数或浮点数。
15. “Inconvertible Types”
当 Java 代码尝试执行非法转换时,会发生“不可转换类型”错误。
域名:12: inconvertible types found : 域名yList<域名s<? extends 域名rface1>> required: 域名yList<域名s<?>> lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
例如,布尔值不能转换为整数。
16. “Missing Return Value”
当 return 语句包含不正确的类型时,您将收到“缺少返回值”消息。例如,以下代码:
public class SavingsAcc2 { private double balance; private double interest; public SavingsAcc2() { balance = 0.0; interest = 域名; } 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; } }
返回以下错误:
域名:29: missing return value return; ^ 域名:35: missing return value return; ^ 域名:41: missing return value return; ^ 3 errors
通常,有一个不返回任何内容的 return 语句。
17. “Cannot Return a Value From Method Whose Result Type Is Void”
当 void 方法尝试返回任何值时,会发生此 Java 错误,例如在以下示例中:
public static void move() { 域名tln("What do you want to do?"); Scanner scan = new Scanner(域名); int userMove = 域名Int(); return userMove; } public static void usersMove(String playerName, int gesture) { int userMove = move(); if (userMove == -1) { break; }
通常通过更改方法签名以匹配 return 语句中的类型来解决此问题。在这种情况下,void 的实例可以更改为 int:
public static int move() { 域名tln("What do you want to do?"); Scanner scan = new Scanner(域名); int userMove = 域名Int(); return userMove; }
18. “Non-Static Variable ... Cannot Be Referenced From a Static Context”
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 } }
要修复“非静态变量...无法从静态上下文中引用”错误,可以做两件事:
该变量可以在签名中声明为静态。
代码可以在静态方法中创建非静态对象的实例。
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[]) { 域名tln("Age is:"+ getAge()); } }
会返回这个错误:
Exception in thread "main" 域名r: 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};