Difference between IllegalAccessError and IllegalA

2019-03-13 08:47发布

Consider this pair of Throwable:

IllegalAccessExceptionextends 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.

IllegalAccessErrorext 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? 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?

3条回答
该账号已被封号
2楼-- · 2019-03-13 08:55

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; 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).

An Error normally indicates that there is something really wrong - there is almost certainly a bug in the software. You should never try to catch Errors. If you are catching the XXXException, there is no immediate reason to also catch the XXXError. The documentation of Error says:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. 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.

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.

An example to generate IllegalAccessException: Via reflection, lookup a private method in a class and try to call it.

An example to generate IllegalAccessError: Create two classes and save them in two source files A.java and B.java. In class A, create a public method, and in class B, call that method. Compile the source files. Now, edit A.java and make the method private, and recompile only A.java (not B.java). Now try running again; B will try to call the method and throw an IllegalAccessError.

There are other pairs of XXXException / XXXError that seem related, but they don't always have exactly matching names; for example ClassNotFoundException / NoClassDefFoundError.

查看更多
smile是对你的礼貌
3楼-- · 2019-03-13 08:56

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.

An IllegalAccessError cannot be thrown by consistently compiled Java code. 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. 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"; i.e. 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? How are the pairs related to each other?

Pass. Check the 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. (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. The whole point of separating Error from Exception is to distinguish the non-recoverable and (potentially) recoverable exceptions.

In this case, there is nothing that a normal application can do in the way of recovering from the IllegalAccessError. If you attempt to repeat the classloader operation that caused the problem, it will just happen again.

查看更多
冷血范
4楼-- · 2019-03-13 09:14

There are several pairs of Exception/Error in java.lang, and all of the following deal with reflective vs. direct usage:

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). So I don't know if and when they are thrown.

查看更多
登录 后发表回答