Java中常见的50个错误、异常及规避技巧

阐述:在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;
}

这种错误消息常常不会准确的定位到错误发生的位置。为了找到错误,建议:

  • 确保所有的左括号有对应匹配的右括号。

  • (使用 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)

4. “找不到符号” 

这是一个非常常见的问题,因为 Java 中的所有标识符都需要在使用之前进行声明。 当编译代码时,编译器并不理解标识符的含义。

在你遇到“找不到符号”消息时可能有很多种原因:

  • 标识符声明时的拼写可能与代码中使用时的拼写不同。

  • 该变量从未被声明。

  • 该变量使用的位置与其声明的作用域不同。

  • 类并未被导入。

请通读关于“找不到符号”错误的讨论,其中也包含创建该问题的示例代码。(@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<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!");
    }
}

下面列举了一些编译器抛出“缺少返回语句”的消息的原因:

  • 返回语句被错误地省略了

  • 一个方法没有返回任何值,但是在方法签名中没有声明为void类型

查看如何修复“缺少返回语句”的 Java 错误的示例(@StackOverflow)

10. “精度可能丢失”

当将超过一个变量可以保存的信息分配给该变量时,会发生“精度可能丢失”问题。如果发生这种情况,超出的信息将会被扔掉。如果这样做没问题,那么代码需要将变量显式地声明为新类型。

下面情况会发生“精度可能丢失”错误:

  • 将一个实数赋值给一个整型变量。

  • 将一个双精度浮点数赋值给一个整型变量。

Java 中原始数据类型解析展示了数据是怎么表示的。(@Oracle)


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)

12. “语句不可达”

“语句不可达”发生在当语句被放在一个不会被执行的位置时候。通常是在 break 语句或 return 语句后面。

for(;;){
   break;
   ... // unreachable statement
}


int i=1;
if(i==1)
  ...
else
  ... // dead code

通常简单地移动 return 语句就能解决这个错误。阅读这个讨论:如何解决语句不可达的 Java 软件错误。(@StackOverflow)

13. “变量 x 可能未被初始化”

这个问题发生在当方法内局部变量在声明时没有被初始化的时候。当一个变量未被初始化但是出现在 if 语句中的时候会发生该错误。

int x;
if (condition) {
    x = 5;
}
System.out.println(x); // x may not have been initialized

阅读这个讨论怎样避免发生“变量 x 可能未被初始化”的错误 (@reddit)

14. “操作符 ... 不能应用于 x”

这个情况发生于当操作符应用于没有定义其使用方法的类型上。

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

当 Java 代码尝试使用 string 类型进行数学计算时会经常出现这个问题。为了解决它,string 需要被转化为 integer 或 float。

阅读这个示例:非数值类型如何导致操作符不能应用于某类型的 Java 软件错误警告。(@StackOverflow)

15. “不能转换的类型”

“不能转换的类型”错误发生在 Java 代码尝试进行非法转换的时候。

TypeInvocationConversionTest.java:12: inconvertible types
found   : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>
required: java.util.ArrayList<java.lang.Class<?>>
    lessRestrictiveClassList = (ArrayList<Class<?>>) 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) <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 软件中如何初始化数组的讨论。(@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

数组的索引是从零开始的,并且比数组长度小了1。通常,在定义数组索引的限制时,要使用“<”而不是“<=”。

可以看看这个例子,索引是如何触发“ArrayIndexOutOfBoundsException”的。 (@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);
    }
}

像数组的索引一样,字符串的索引是从零开始的。索引字符串时,最后一个字符的索引值比字符串的长度小1。 “StringIndexOutOfBoundsException”这个错误消息一般都意味着索引正在尝试访问不存在于字符串中的字符。

这里有一个说明了“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”这样的错误。

阅读这里的教程可以了解如何避免 NoSuchMethodFoundError 错误。 (@javacodegeeks)

26. “NoSuchProviderException”

当请求了一个不可用的安全方案提供方(Security Provider)的时候,就会引发“NoSuchProviderException” (@alvinalexander):

javax.mail.NoSuchProviderException

如果你在尝试找出“NoSuchProviderException”为什么会发生的原因,请进行如下检查:

  • JRE 配置。

  • 配置中的 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”

“ArrayStoreException”会发生在向 Java 的数组中转换元素受到转换规则限制而发生中断的时候。例如,这个来自于 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”

这个错误消息的意思是网络上的类定义文件可能出问题了。如下是服务器端的错误消息示例(@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

数据管道中断发生的原因一般包括如下这些

  • 磁盘的暂存空间已经耗尽。

  • RAM可能被堵塞了。

  • 数据流可能已经损坏了。

  • 读取管道的进程可能已经关闭了。

可以读一读这里这篇关于什么是“broken pipe”错误的讨论。 (@StackOverflow)

31. “Could Not Create Java Virtual Machine”

当 Java 代码尝试使用错误的参数来启动 Java 时,一般会产生这样的错误消息 (@ghacksnews):

Error: Could not create the Java Virtual Machine

Error: A fatal exception has occurred. Program will exit.

它通常是由于代码中的声明中或者为其分配适当的内存时有错误而引起的。

可以读一读这里关于如何修复“Could not create Java Virtual Machine”错误的讨论。(@StackOverflow)

32. “class file contains wrong class”

“class file contains wrong class”问题一般会发生在 Java 代码尝试在错误的目录中寻找类文件的时候,产生类似于如下所示的错误消息:

MyTest.java:10: cannot access MyStruct
bad class fileD:\Java\test\MyStruct.java
file does not contain class MyStruct
Please remove or make sure it appears in the correct subdirectory of the classpath.
MyStruct ms new MyStruct();
^

要修复此问题,如下提示可以提供一些帮助:

  • 确保源文件的名称和类的名称匹配——包括大小写。

  • 检查包的说明语句是否正确或者缺失。

  • 确保源文件位于正确的目录。

可以读一读这里关于如何修复“类文件包含错误类”错误的讨论。 (@StackOverflow)

33. “ClassCastException”

“ClassCastException” 消息表示 Java 代码正尝试将对象转换到一个错误的类型。在下面这个来自于 Java 概念日有所进(Java Concept of the Day)的实例中, 运行着这样的程序:

package com;
class A
{
    int i = 10;
}

class B extends A
{
    int j = 20;
}

class C extends B
{
    int k = 30;
}

public class ClassCastExceptionDemo
{
    public static void main(String[] args)
    {
        A a = new B();   //B type is auto up casted to A type
        B b = (B) a;     //A type is explicitly down casted to B type.
        C c = (C) b;    //Here, you will get class cast exception
        System.out.println(c.k);
    }
}

这会导致如下错误:

Exception in thread “main” java.lang.ClassCastException: com.B cannot be cast to com.C
at com.ClassCastExceptionDemo.main(ClassCastExceptionDemo.java:23)

Java 代码会创建一个类和子类的层级结构。为了避免 “ClassCastException” 错误,请确保新的类型归属于正确的类或者它的父类。如果使用了泛型的话,这些错误就可以在编译时被捕获到。

可以读一读这篇关于如何修复 “ClassCastException” 错误的教程。 (@java_concept)

34. “ClassFormatError”

“ClassFormatError” 消息指代的是一个链接错误,发生在一个类文件不能被读取或者解释为一个类文件的时候。

Caused by: java.lang.ClassFormatError: Absent Code attribute in method that is
        not native or abstract in class file javax/persistence/GenerationType

at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

关于“ClassFormatError”错误为什么会发生,有几种可能:

  • 类文件是以 ASCII 模式而不是二进制模式来上传的。

  • 网页服务器是以二进制而非 ASCII 来发送类文件的。

  • 可能有类路径错误阻止了代码找到类文件。

  • 如果类被加载了两次,第二次就会导致这个异常被抛出来。

  • 使用了一个老版本的 Java 运行时。

可以读一读这里关于什么会引发“ClassFormatError”的讨论。 (@StackOverflow)

35. “ClassNotFoundException”

“ClassNotFoundException” 只会发生于运行时——意味着本存在于编译时可是在运行时却丢失了。这是一个链接错误。

非常类似于 “NoClassDefFoundError”,如下情况就有可能让这样的问题发生:

  • 文件不在正确的目录。

  • 类的名称必须跟文件的名称保持一致(不包括扩展名)。名称对大小写是敏感的。

可以读一读这里关于什么会导致“ClassNotFoundException“发生的讨论,以了解更多情况 (@StackOverflow).


36. “ExceptionInInitializerError”

这个 Java 问题会在静态初始化有问题时发生 (@GitHub)。当 Java 代码稍后要用到这个类时, 将会发生“NoClassDefFoundError” 错误.

java.lang.ExceptionInInitializerError
  at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:54)
  at org.eclipse.mat.parser.internal.SnapshotFactory.parse(SnapshotFactory.java:193)
  at org.eclipse.mat.parser.internal.SnapshotFactory.openSnapshot(SnapshotFactory.java:106)
  at com.squareup.leakcanary.HeapAnalyzer.openSnapshot(HeapAnalyzer.java:134)
  at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:87)
  at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
  at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:145)
  at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.NullPointerException: in == null
  at java.util.Properties.load(Properties.java:246)
  at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:28)
  at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:13)
  ... 10 more

要修复此问题还需要更多的信息。在代码中使用 getCause()  可以返回导致被返回的错误发生的异常对象。

可以读一读这里关于如何跟踪 ExceptionInInitializerError 的发生原因的讨论。 (@StackOverflow)

37. “IllegalBlockSizeException”

“IllegalBlockSizeException” 会发生在解密时消息长度不是8位的倍数的时候。这里有一个来自于 ProgramCreek.com 的例子(@ProgramCreek):

@Override
protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
    try {
        byte[] encoded = key.getEncoded();
        return engineDoFinal(encoded, 0, encoded.length);
    } catch (BadPaddingException e) {
        IllegalBlockSizeException newE = new IllegalBlockSizeException();
        newE.initCause(e);
        throw newE;
    }
}

“IllegalBlockSizeException” 可能由如下状况所导致:

  • 使用的加解密算法不一致。

  • 被解密的消息在传递过来的途中被截断或者产生了乱码。

可以读一读这里关于如何预防 IllegalBlockSizeException 错误发生的讨论(@StackOverflow)

38. “BadPaddingException”

“BadPaddingException”会发生于解密时填充块被用来创建一个可以用 8 位的倍数来计算长度的消息的时候。这里有一个来自于 Stack Overflow 的例子(@StackOverflow):

javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)

被加密的数据是二进制的,因此不要尝试着在一个字符串中去存储它,或者也有可能是加密期间数据没有进行恰当的填充。

可以读一读这里关于如何防止 BadPaddingException 发生的讨论。 (@StackOverflow)

39. “IncompatibleClassChangeError”

“IncompatibleClassChangeError” 是链接错误 LinkageError 的一种形式,会在一个基类在其子类已经编译过了之后发生了概念时发生。这里有一个来自于 How to Do in Java 的例子 (@HowToDoInJava):

Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at net.sf.cglib.core.DebuggingClassWriter.toByteArray(DebuggingClassWriter.java:73)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:116)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
at net.sf.cglib.proxy.Enhancer.(Enhancer.java:69)

当 “IncompatibleClassChangeError” 发生时,有能发生了如下状况:

  • 忘记了在主方法的 static 关键词。

  • 一个合法的类被非法地使用。

  • 一个类发生了修改,可是还有其它类使用原来的签名来引用它。可以尝试把所有的类文件都删除掉然后全部重新编译。

可尝试这些步骤来解决“IncompatibleClassChangeError”问题 (@javacodegeeks)

40. “FileNotFoundException”

这个 Java 软件错误消息会在指定路径名上的文件不存在是被抛出来。

@Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    if (uri.toString().startsWith(FILE_PROVIDER_PREFIX)) {
        int m = ParcelFileDescriptor.MODE_READ_ONLY;
        if (mode.equalsIgnoreCase("rw")) m = ParcelFileDescriptor.MODE_READ_WRITE;
        File f = new File(uri.getPath());
        ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, m);
        return pfd;
    } else {
        throw new FileNotFoundException("Unsupported uri: " + uri.toString());
    }
}

出来指定路径名上的文件不存在之外,这种问题也有可能意思是存在的文件是不可被访问的。

可以读一读这里关于为什么“FileNotFoundException”会被抛出的讨论。(@StackOverflow)

41. “EOFException”

“EOFException”会在输出时不经意抵达了文件的终点或者流的终点时被抛出。这里有一个来自于 JavaBeat 的抛出了一个 EOFException 的应用程序示例:

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ExceptionExample {
    public void testMethod1() {
        File file = new File("test.txt");
        DataInputStream dataInputStream = null;
        try {
            dataInputStream = new DataInputStream(new FileInputStream(file));
            while (true) {
                dataInputStream.readInt();
            }
        } catch (EOFException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (dataInputStream != null) {
                    dataInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        ExceptionExample instance1 = new ExceptionExample();
        instance1.testMethod1();
    }
}

运行上述程序会导致如下异常:

java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at logging.simple.ExceptionExample.testMethod1(ExceptionExample.java:16)
at logging.simple.ExceptionExample.main(ExceptionExample.java:36)

当后面已经没有数据可供输出了,可 DataInputStream 仍在尝试读取流中的数据, “EOFException” 就会被抛出来。它也可以发生于 ObjectInputStream 和 RandomAccessFile 类的逻辑里面。

可以读一读这里关于在运行 Java 软件时“EOFException”什么时候会发生的讨论。(@StackOverflow)

42. “UnsupportedEncodingException”

该 Java 软件错误消息会在字符编码不被环境所支持的时候产生 (@Penn)。

public UnsupportedEncodingException()

所使用的 Java 虚拟机不支持某一种给定的字符集是有可能的。

可以读一读这里关于如何在运行 Java 软件时处理“UnsupportedEncodingException”的讨论 (@StackOverflow)

43. “SocketException”

“SocketException” 在创建或者访问套接字的时候有错误发生(@ProgramCreek).

public void init(String contextName, ContextFactory factory) {
    super.init(contextName, factory);

    String periodStr = getAttribute(PERIOD_PROPERTY);
    if (periodStr != null) {
        int period = 0;
        try {
            period = Integer.parseInt(periodStr);
        } catch (NumberFormatException nfe) {}
        if (period <= 0) {
            throw new MetricsException("Invalid period: " + periodStr);
        }
        setPeriod(period);
    }

    metricsServers =
        Util.parse(getAttribute(SERVERS_PROPERTY), DEFAULT_PORT);

    unitsTable = getAttributeTable(UNITS_PROPERTY);
    slopeTable = getAttributeTable(SLOPE_PROPERTY);
    tmaxTable = getAttributeTable(TMAX_PROPERTY);
    dmaxTable = getAttributeTable(DMAX_PROPERTY);

    try {
        datagramSocket = new DatagramSocket();
    } catch (SocketException se) {
        se.printStackTrace();
    }
}

该异常一般会在最大连接数因为如下原因而满了的时候被抛出来:

  • 已经没有更多的网络端口可以供应该应用程序了。

  • 系统没有充足的内存来支持新的连接。

可以读一读这里关于在运行 Java 软件时如何解决“SocketException”问题的讨论。(@StackOverflow)

44. “SSLException”

该 Java 软件错误消息会在有跟 SSL 相关的操作失败时发生。如下是一个来自于 Atlassian 的示例(@Atlassian):

com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
   at com.sun.jersey.client.apache.ApacheHttpClientHandler.handle(ApacheHttpClientHandler.java:202)
   at com.sun.jersey.api.client.Client.handle(Client.java:365)
   at com.sun.jersey.api.client.WebResource.handle(WebResource.java:556)
   at com.sun.jersey.api.client.WebResource.get(WebResource.java:178)
   at com.atlassian.plugins.client.service.product.ProductServiceClientImpl.getProductVersionsAfterVersion(ProductServiceClientImpl.java:82)
   at com.atlassian.upm.pac.PacClientImpl.getProductUpgrades(PacClientImpl.java:111)
   at com.atlassian.upm.rest.resources.ProductUpgradesResource.get(ProductUpgradesResource.java:39)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at com.atlassian.plugins.rest.common.interceptor.impl.DispatchProviderHelper$ResponseOutInvoker$1.invoke(DispatchProviderHelper.java:206)
   at com.atlassian.plugins.rest.common.interceptor.impl.DispatchProviderHelper$1.intercept(DispatchProviderHelper.java:90)
   at com.atlassian.plugins.rest.common.interceptor.impl.DefaultMethodInvocation.invoke(DefaultMethodInvocation.java:61)
   at com.atlassian.plugins.rest.common.expand.interceptor.ExpandInterceptor.intercept(ExpandInterceptor.java:38)
   at com.atlassian.plugins.rest.common.interceptor.impl.DefaultMethodInvocation.invoke(DefaultMethodInvocation.java:61)
   at com.atlassian.plugins.rest.common.interceptor.impl.DispatchProviderHelper.invokeMethodWithInterceptors(DispatchProviderHelper.java:98)
   at com.atlassian.plugins.rest.common.interceptor.impl.DispatchProviderHelper.access$100(DispatchProviderHelper.java:28)
   at com.atlassian.plugins.rest.common.interceptor.impl.DispatchProviderHelper$ResponseOutInvoker._dispatch(DispatchProviderHelper.java:202)
   ...
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
   ...
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
   ...
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

如下情况有可能会导致这样的问题发生:

  • 服务器或者客户端上的证书已经过期了。

  • 服务器上的端口已经被重设成另外的一个。

可以读一读这里关于在 Java 软件中什么会导致“SSLException” 错误发生的讨论。(@StackOverflow)

45. “MissingResourceException”

“MissingResourceException” 会在某个资源丢失时发生。如果资源已经处于正确的类路径之下的话,那就一般是因为一个属性配置文件并没有被恰当的进行了配置。这里有一个示例 (@TIBCO):

java.util.MissingResourceException: Can't find bundle for base name localemsgs_en_US, locale en_US
java.util.ResourceBundle.throwMissingResourceException
java.util.ResourceBundle.getBundleImpl
java.util.ResourceBundle.getBundle
net.sf.jasperreports.engine.util.JRResourcesUtil.loadResourceBundle
net.sf.jasperreports.engine.util.JRResourcesUtil.loadResourceBundle

可以读一读这里关于在运行 Java 软件时如何修复“MissingResourceException”问题的讨论。

46. “NoInitialContextException”

“NoInitialContextException”会在 Java 应用程序想要执行命名操作可是不能创建一个链接的时候发生(@TheASF).

[java] Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system propertyor as an applet parameteror in an application resource file:  java.naming.factory.initial
[java]     at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
[java]     at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
[java]     at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:284)
[java]     at javax.naming.InitialContext.lookup(InitialContext.java:351)
[java]     at org.apache.camel.impl.JndiRegistry.lookup(JndiRegistry.java:51)

这会是一个解决起来比较复杂的问题,不过还是有一些可能的问题会导致 “NoInitialContextException” 错误消息的产生:

  • 应用程序可能没有正常的证书来建立连接。

  • 代码也许没有确认 JNDI 所需要的实现。

  • InitialContext 类可能没有正确的属性来进行配置。

可以读一读这里关于在运行 Java 应用程序时“NoInitialContextException” 意味着的是什么的讨论。 (@StackOverflow)

47. “NoSuchElementException”

“NoSuchElementException” 会在一个迭代 (比如一个 for 循环)尝试去访问已经没有了的下一个 元素时发生。

public class NoSuchElementExceptionDemo{

    public static void main(String args[]) {
        Hashtable sampleMap = new Hashtable();
        Enumeration enumeration = sampleMap.elements();
        enumeration.nextElement();  //java.util.NoSuchElementExcepiton here because enumeration is empty
    }
}

Output:
Exception in thread "main" java.util.NoSuchElementException: Hashtable Enumerator
        at java.util.Hashtable$EmptyEnumerator.nextElement(Hashtable.java:1084)
        at test.ExceptionTest.main(NoSuchElementExceptionDemo.java:23)

     

“NoSuchElementException” 可以被如下这些方法抛出:

  • Enumeration::nextElement()

  • NamingEnumeration::next()

  • StringTokenizer::nextElement()

  • Iterator::next()

可以读一读这个关于在 Java 软件中如何修复 “NoSuchElementException”的教程。(@javinpaul)

48. “NoSuchFieldError”

该 Java 软件错误消息会在一个应用程序尝试去访问一个对象中的某个域,可是指定域在类中不复存在时发生 (@sourceforge).

public NoSuchFieldError()

该错误一般会在编译器中被捕获,但如果一个类的定义在编译和运行之间被修改了话,也会被捕获到。

可以读一读这里关于在 Java 软件中如何找出是什么导致了“NoSuchFieldError”的讨论。@StackOverflow



49. “NumberFormatException”

该 Java 软件错误消息会在应用程序尝试将一个字符串转换成一个数值类型, 而该数值并非一个有效的数字字符串时发生(@alvinalexander)。

package com.devdaily.javasamples;

public class ConvertStringToNumber {

    public static void main(String[] args) {
        try {
            String s = "FOOBAR";
            int i = Integer.parseInt(s);
            // this line of code will never be reached
            System.out.println("int value = " + i);
        }
        catch (NumberFormatException nfe) {
            nfe.printStackTrace();
        }
    }

}

当存在如下状况时 “NumberFormatException” 会被抛出:

  • 数值中前面或后面的空格。

  • 符号不在数值的前头。

  • 数值有逗号。

  • 本地化逻辑可能不会将其识别为一个有效的数值。

  • 数值太大,给定的数值类型装不下。

可以读一读这里关于在运行 Java 软件时如何避免“NumberFormatException”的讨论。(@StackOverflow).

50. “TimeoutException”

该 Java 软件错误消息会在有一个阻塞操作超时的时候发生:

private void queueObject(ComplexDataObject obj) throws TimeoutException, InterruptedException {
    if (!queue.offer(obj, 10, TimeUnit.SECONDS)) {
        TimeoutException ex = new TimeoutException("Timed out waiting for parsed elements to be processed. Aborting.");
        throw ex;
    }
}

可以读一读这里关于在运行 Java 软件时如何处理 “TimeoutException”的讨论。(@StackOverflow).





原文链接

  • 10
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值