IllegalAccessError和IllegalAccessException之间的区别

时间:2010-06-19 06:45:01

标签: java exception-handling error-handling

考虑这对Throwable

  

IllegalAccessException extends Exception

     

当应用程序尝试反射性地创建实例(数组除外),设置或获取字段或调用方法时抛出,但当前正在执行的方法无法访问指定类的字段定义,方法或构造函数。

     

IllegalAccessError ext IncompatibleClassChangeError ext LinkageError ext Error

     

如果应用程序试图访问或修改字段,或调用它无权访问的方法,则抛出该文件。

     

通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。

问题

  • 有人可以提供一个代码示例,其中每个都被抛出?
  • 名字的相似性是否意味着两者之间的关系,还是只是纯粹的巧合?
  • 还有其他XXXErrorXXXException组合吗?这些对是如何相互关联的?
  • 如果您在try对中明确catchException/Error,那么您还应该catch另一个吗?

3 个答案:

答案 0 :(得分:8)

  

有人可以给出一个代码示例,其中每个都被抛出?

当您尝试使用反射来调用方法或读取或写入Java可见性规则禁止的字段时,将引发IllegalAccessException

一致编译的Java代码无法抛出IllegalAccessError。例如,当您加载试图调用方法的类或读取或写入Java可见性规则禁止的另一个类中的字段时,就会发生这种情况。这是编译器通常会阻止的,所以这意味着类有严重错误。无论如何,这被认为是“错误”;即不可恢复,并且类加载器将拒绝加载违规类。

  

名字的相似性是否意味着两者之间的关系,还是只是纯粹的巧合?

两者之间有明确的关系。不同之处在于两者发生的情况。

  

还有其他XXXError和XXXException组合吗?这些对是如何相互关联的?

传递。检查javadocs。

  

如果您明确尝试在异常/错误对中捕获一个,是否还要捕获另一个?

可能不是。 XXXError和XXXException通常在不同的情况下发生。 (这当然适用于反射与类加载器。)

此外,作为一般规则,您不应尝试捕获Error的子类型并从中恢复。将ErrorException分开的重点是区分不可恢复和(可能)可恢复的异常。

在这种情况下,普通应用程序无法从IllegalAccessError恢复。如果您尝试重复导致问题的类加载器操作,它将再次发生。

答案 1 :(得分:6)

描述已经解释了其中的一些内容:当您使用反射来访问字段或调用无法访问的方法时,会引发Exception;当你直接这样做时会引发Error(并且由于某种原因,编译器没有机会捕获它 - 例如当你有一个旧版本的类文件时,你在其中的字段或方法'尝试使用是私人的。)

Error通常表示确实存在错误 - 软件中几乎肯定存在错误。你永远不应该试图抓住Error。如果您正在捕捉XXXException,则没有立即抓住XXXError的理由。 Error的文档说:

  

错误是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。大多数此类错误都是异常情况。 ThreadDeath错误虽然是“正常”条件,但也是Error的子类,因为大多数应用程序都不应该尝试捕获它。

     

不需要在throws子句中声明任何可能在方法执行期间抛出但未捕获的Error子类,因为这些错误是永远不会发生的异常情况。

生成IllegalAccessException的示例:通过反射,在类中查找私有方法并尝试调用它。

生成IllegalAccessError的示例:创建两个类并将它们保存在两个源文件A.javaB.java中。在课程A中,创建一个公共方法,并在类B中调用该方法。编译源文件。现在,编辑A.java并将该方法设为私有,并仅重新编译A.java(不是B.java)。现在再试一次; B将尝试调用该方法并抛出IllegalAccessError

还有其他成对的XXXException / XXXError似乎相关,但它们并不总是具有完全匹配的名称;例如ClassNotFoundException / NoClassDefFoundError

答案 2 :(得分:1)

java.lang中存在多对异常/错误,以下所有内容都涉及反射与直接使用:

IllegalAccessException / IllegalAccessError
InstantiationException / InstantiationError
ClassNotFoundException / NoClassDefFoundError
NoSuchFieldException / NoSuchFieldError
NoSuchMethodException / NoSuchMethodError

其他例子是:

java.awt.AWTException / java.awt.AWTError
java.io.IOException / java.io.IOError

到目前为止,我不知道存在这两个错误,并且它们没有从Javadoc(1.6)中的其他类引用。所以我不知道他们是否以及何时被抛出。