编译器错误
编译器错误消息在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;
}
这种错误消息常常不会准确的定位到错误发生的位置。为了找到错误,建议:
-
确保所有的左括号有对应匹配的右括号。
-
(使用 IDE,译者注)在代码行前的提示中检查。这种 Java 软件错误不要由编译器来关注,应该把更后面的工作交给它。
-
有时候一个字符,比如一个左括号不应该写在 Java 代码的开始处。这样造成的结果是开发者不会写右括号去凑成一对。
对照这个“一个缺失的括号”的例子来制造一个错误。
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 = new NFLPlayersReference [3];
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 表达式中的元素又没有使用下划线“\”进行转义。
阅读这篇《未封闭的 String 表达式的讨论》。
3. “非法的表达式开头”
出现“非法表达式开头”错误的原因有很多。但它最终归类于一个不太有用的错误消息之一。有些开发者说这是由糟糕的代码造成的。
通常,创建表达式是用于生成新值或为变量赋值。编译器期望找到一个表达式,但找不到它,因为语法不符合预期。 (@StackOverflow)在下面这些语句中可以找到此错误。
} // ADD IT HERE
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.");
}
}
} // REMOVE IT FROM HERE
}
请浏览下这个讨论,关于如何解决“非法表达式开头”错误的方法 。 (@StackOverflow)
5. “公共类 XXX 应该在文件中出现”
“公共类 XXX 应该在文件中出现”这个消息出现在类XXX和Java程序文件名不一致时。源代码只有在类名和 Java 文件名一样时才会被编译。(@coderanch):
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);
}
}
要修复这种情况:
-
类名和文件名一样。
-
确保这两个名字的大小写一致。
看 “公共类 XXX 应该在文件中出现”错误的例子。(@StackOverflow)
6. “不兼容类型”
“不兼容的类型”是在赋值语句中尝试将变量与类型表达式匹配时触发的逻辑错误。通常是在代码尝试将文本字符写入到整数中时出现,反之亦然。 这不是 Java 语法错误。 (@StackOverflow)
test.java:78: error: incompatible types
return stringBuilder.toString();
^
required: int
found: String
1 error
当编译器给出“不兼容的类型”消息时,确实没有一个简单的修复方案:
-
有可以转换类型的函数。
-
开发人员可能需要按照代码的预期修改之。
看一个例子,来说明如何通过使用字符串到整型的赋值来创建"不兼容类型"错误。(@StackOverflow)
7. “无效的方法声明;需求返回类型”
此错误表示方法签名中没有明确说明方法的返回类型。
public class Circle
{
private double radius;
public CircleR(double r)
{
radius = r;
}
public diameter()
{
double d = radius * 2;
return d;
}
}
有几种方式会触发“无效的方法声明; 需求返回类型“错误:
-
忘记说明返回类型
-
如果方法没有返回值,那么需要用“void”表示方法签名中的返回类型。
-
构造函数名称不需要说明返回类型。 但是,如果构造函数名称中出现错误,那么编译器会将构造函数视为没有指定类型的方法。
下面是一个例子讲述构造函数命名怎么触发“无效的方法声明;需求返回类型”的错误 。 (@StackOverflow)
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
方法在被调用时期望获取在方法声明中定义的某些参数。 检查方法声明、谨慎调用方法,以确保声明和调用的参数是兼容的。
这个讨论说明了 Java 错误消息如何识别在方法声明和方法调用中由参数导致的不兼容性。(@StackOverflow)
9. “缺少返回语句”
当一个方法缺少返回语句时,会发生“缺少返回语句”错误。 每一个有返回值的方法(非 void 类型)必须有一句字面上的语句用以返回返回值,以便在方法外调用该值。
public String[] OpenFile() throws IOException {
Map 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!");
}
}
下面列举了一些编译器抛出“缺少返回语句”的消息的原因:
-
返回语句被错误地省略了
-
一个方法没有返回任何值,但是在方法签名中没有声明为void类型
11. “解析时到达文件末尾”
这个错误信息经常发生在 Java 程序缺少“}”符号时。通常在代码末加上“}”符号能很快解决这个问题。
public class mod_MyMod extends BaseMod
public 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 }
代码编写工具和适当的代码缩进可以更容易地找到这些不对的大括号。
这个示例展示了缺少的大括号如何造成“解析时到达文件结尾”的错误消息。 (@StackOverflow)
15. “不能转换的类型”
“不能转换的类型”错误发生在 Java 代码尝试进行非法转换的时候。
TypeInvocationConversionTest.java:12: inconvertible types
found : java.util.ArrayList>
required: java.util.ArrayList>
lessRestrictiveClassList = (ArrayList>) classList;
^
例如,boolean 不能转换为 int。
阅读这个关于在 Java 软件中寻找转换不能转换类型的方法的讨论。(@StackOverflow)
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
通常,那些返回语句没有返回任何东西。
阅读这个关于怎样避免“缺少返回值”的 Java 软件错误消息的讨论。(@coderanch)
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;
}
阅读这个关于怎样解决“返回类型为 void 的方法不能返回一个值”的问题的讨论。(@StackOverflow)
18. “非静态变量 ... 不能在静态上下文中被引用”
当编译器尝试在一个静态方法中访问一个非静态变量时会发生该错误。 (@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
}
}
为了解决“非静态变量 ... 不能在静态上下文中被引用”的错误,有下述两种方法:
-
在签名中将变量声明为静态变量。
-
在静态方法中创建一个非静态对象的示例
阅读这个指南,解释了静态和非静态变量的不同点。(@sitesbay)
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) Not Initialized” (数组未初始化)
当数组已声明但未初始化时,你将得到“(array)
以下代码是可以接受的:
AClass[] array = {object1, object2}
下面也是可以的:
AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;
但是这个不行:
AClass[] array;
...
array = {object1, object2};