考虑这对Throwable
:
IllegalAccessException
extends Exception
当应用程序尝试反射性地创建实例(数组除外),设置或获取字段或调用方法时抛出,但当前正在执行的方法无法访问指定类的字段定义,方法或构造函数。
IllegalAccessError
ext IncompatibleClassChangeError ext LinkageError ext Error
如果应用程序试图访问或修改字段,或调用它无权访问的方法,则抛出该文件。
通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。
XXXError
和XXXException
组合吗?这些对是如何相互关联的?try
对中明确catch
到Exception/Error
,那么您还应该catch
另一个吗?答案 0 :(得分:8)
有人可以给出一个代码示例,其中每个都被抛出?
当您尝试使用反射来调用方法或读取或写入Java可见性规则禁止的字段时,将引发IllegalAccessException
。
一致编译的Java代码无法抛出IllegalAccessError
。例如,当您加载试图调用方法的类或读取或写入Java可见性规则禁止的另一个类中的字段时,就会发生这种情况。这是编译器通常会阻止的,所以这意味着类有严重错误。无论如何,这被认为是“错误”;即不可恢复,并且类加载器将拒绝加载违规类。
名字的相似性是否意味着两者之间的关系,还是只是纯粹的巧合?
两者之间有明确的关系。不同之处在于两者发生的情况。
还有其他XXXError和XXXException组合吗?这些对是如何相互关联的?
传递。检查javadocs。
如果您明确尝试在异常/错误对中捕获一个,是否还要捕获另一个?
可能不是。 XXXError和XXXException通常在不同的情况下发生。 (这当然适用于反射与类加载器。)
此外,作为一般规则,您不应尝试捕获Error
的子类型并从中恢复。将Error
与Exception
分开的重点是区分不可恢复和(可能)可恢复的异常。
在这种情况下,普通应用程序无法从IllegalAccessError
恢复。如果您尝试重复导致问题的类加载器操作,它将再次发生。
答案 1 :(得分:6)
描述已经解释了其中的一些内容:当您使用反射来访问字段或调用无法访问的方法时,会引发Exception
;当你直接这样做时会引发Error
(并且由于某种原因,编译器没有机会捕获它 - 例如当你有一个旧版本的类文件时,你在其中的字段或方法'尝试使用是私人的。)
Error
通常表示确实存在错误 - 软件中几乎肯定存在错误。你永远不应该试图抓住Error
。如果您正在捕捉XXXException
,则没有立即抓住XXXError
的理由。 Error
的文档说:
错误是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。大多数此类错误都是异常情况。 ThreadDeath错误虽然是“正常”条件,但也是Error的子类,因为大多数应用程序都不应该尝试捕获它。
不需要在throws子句中声明任何可能在方法执行期间抛出但未捕获的Error子类,因为这些错误是永远不会发生的异常情况。
生成IllegalAccessException
的示例:通过反射,在类中查找私有方法并尝试调用它。
生成IllegalAccessError
的示例:创建两个类并将它们保存在两个源文件A.java
和B.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)中的其他类引用。所以我不知道他们是否以及何时被抛出。