简体   繁体   English

IllegalAccessError和IllegalAccessException之间的区别

[英]Difference between IllegalAccessError and IllegalAccessException

Consider this pair of Throwable : 考虑这对Throwable

IllegalAccessException extends Exception IllegalAccessException extends Exception

Thrown when an application tries to reflectively create an instance (other than an array), set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class, field, method or constructor. 当应用程序尝试反射性地创建实例(数组除外),设置或获取字段或调用方法时抛出,但当前正在执行的方法无法访问指定类,字段,方法或构造函数的定义。

IllegalAccessError ext IncompatibleClassChangeError ext LinkageError ext Error IllegalAccessError ext IncompatibleClassChangeError ext LinkageError ext Error

Thrown if an application attempts to access or modify a field, or to call a method that it does not have access to. 如果应用程序尝试访问或修改字段,或调用其无权访问的方法,则抛出该异常。

Normally, this error is caught by the compiler; 通常,编译器会捕获此错误; this error can only occur at run time if the definition of a class has incompatibly changed. 如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。

Questions 问题

  • Can someone give a code example where each is thrown? 有人可以给出每个抛出的代码示例吗?
  • Does the similarity in name imply relationship between the two, or is it just pure coincidence? 名字的相似性是否意味着两者之间的关系,还是仅仅是纯粹的巧合?
  • Are there other XXXError and XXXException combo? 还有其他XXXErrorXXXException组合吗? How are the pairs related to each other? 这些对是如何相互关联的?
  • If you explicitly try to catch one in an Exception/Error pair, should you also catch the other? 如果您明确tryException/Error对中catch一个,您是否还应该catch另一个?

Can someone give a code example where each is thrown? 有人可以给出每个抛出的代码示例吗?

The IllegalAccessException is thrown when you try to use reflection to invoke a method or read or write a field that is forbidden by the Java visibility rules. 当您尝试使用反射来调用方法或读取或写入Java可见性规则禁止的字段时,将引发IllegalAccessException

An IllegalAccessError cannot be thrown by consistently compiled Java code. 一致编译的Java代码不能抛出IllegalAccessError It occurs when for example, you load a class that attempts to invoke a method or read or write a field in another class that is forbidden by the Java visibility rules. 例如,当您加载试图调用方法的类或读取或写入Java可见性规则禁止的另一个类中的字段时,就会发生这种情况。 This is something that the compiler would normally prevent, so this means there is something seriously wrong with the classes. 这是编译器通常会阻止的,所以这意味着类有严重错误。 At any rate, this is considered to be an "error"; 无论如何,这被认为是“错误”; ie not recoverable, and the classloader will refuse to load the offending class(es). 即不可恢复,类加载器将拒绝加载违规类。

Does the similarity in name imply relationship between the two, or is it just pure coincidence? 名字的相似性是否意味着两者之间的关系,还是仅仅是纯粹的巧合?

There is a clear relationship between the two. 两者之间有明确的关系。 The difference is the circumstances in which the two occur. 不同之处在于两者发生的情况。

Are there other XXXError and XXXException combo? 还有其他XXXError和XXXException组合吗? How are the pairs related to each other? 这些对是如何相互关联的?

Pass. 通过。 Check the javadocs. 检查javadocs。

If you explicitly try to catch one in an Exception/Error pair, should you also catch the other? 如果您明确尝试在异常/错误对中捕获一个,您是否还应该捕获另一个?

Probably not. 可能不是。 The XXXError and XXXException generally occur in different circumstances. XXXError和XXXException通常在不同的情况下发生。 (This certainly applies to the reflective vs. classloader ones.) (这当然适用于反射与类加载器。)

Besides, as a general rule you should not attempt to catch and recover from subtypes of Error . 此外,作为一般规则,您不应尝试捕获并从Error子类型中恢复。 The whole point of separating Error from Exception is to distinguish the non-recoverable and (potentially) recoverable exceptions. ErrorException分开的关键是区分不可恢复和(可能)可恢复的异常。

In this case, there is nothing that a normal application can do in the way of recovering from the IllegalAccessError . 在这种情况下,普通应用程序无法从IllegalAccessError中恢复。 If you attempt to repeat the classloader operation that caused the problem, it will just happen again. 如果您尝试重复导致问题的类加载器操作,它将再次发生。

The description already explains some of it: the Exception is thrown when you use reflection to access a field or invoke a method that is not accessible; 描述已经解释了一些:当您使用反射来访问字段或调用不可访问的方法时,抛出Exception ; the Error is thrown when you do so directly (and for some reason the compiler did not have the chance to catch it - for example when you have an old version of a class file around, in which the field or method you're trying to use is private). 直接执行此操作时会抛出Error (由于某种原因,编译器没有机会捕获它 - 例如,当您有一个旧版本的类文件时,您正在尝试使用该字段或方法使用是私人的)。

An Error normally indicates that there is something really wrong - there is almost certainly a bug in the software. Error通常表示存在严重错误 - 软件中几乎肯定存在错误。 You should never try to catch Error s. 你永远不应该试图捕捉Error If you are catching the XXXException , there is no immediate reason to also catch the XXXError . 如果您正在捕获XXXException ,则没有立即理由捕获XXXError The documentation of Error says: Error的文档说:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Error是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。 Most such errors are abnormal conditions. 大多数此类错误都是异常情况。 The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it. ThreadDeath错误,虽然是“正常”条件,但也是Error的子类,因为大多数应用程序不应该尝试捕获它。

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. 一个方法不需要在其throws子句中声明在执行方法期间可能抛出但未捕获的任何Error类,因为这些错误是永远不应发生的异常情况。

An example to generate IllegalAccessException : Via reflection, lookup a private method in a class and try to call it. 生成IllegalAccessException的示例:通过反射,在类中查找私有方法并尝试调用它。

An example to generate IllegalAccessError : Create two classes and save them in two source files A.java and B.java . 生成IllegalAccessError的示例:创建两个类并将它们保存在两个源文件A.javaB.java In class A , create a public method, and in class B , call that method. 在类A ,创建一个公共方法,在类B ,调用该方法。 Compile the source files. 编译源文件。 Now, edit A.java and make the method private, and recompile only A.java (not B.java ). 现在,编辑A.java并将该方法A.java私有,并仅重新编译A.java (而不是B.java )。 Now try running again; 现在再试一次; B will try to call the method and throw an IllegalAccessError . B将尝试调用该方法并抛出IllegalAccessError

There are other pairs of XXXException / XXXError that seem related, but they don't always have exactly matching names; 还有其他XXXException / XXXError对似乎相关,但它们并不总是具有完全匹配的名称; for example ClassNotFoundException / NoClassDefFoundError . 例如ClassNotFoundException / NoClassDefFoundError

There are several pairs of Exception/Error in java.lang , and all of the following deal with reflective vs. direct usage: java.lang有几对异常/错误,以下所有内容都涉及反射与直接用法:

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

Other examples are: 其他例子是:

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

Until now, I didn't know these two errors existed, and they are not referenced from other classes in the Javadoc (1.6). 到目前为止,我不知道存在这两个错误,并且它们没有从Javadoc中的其他类引用(1.6)。 So I don't know if and when they are thrown. 所以我不知道他们是否以及何时被抛出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM