How to differentiate between Programmer and JVM Exceptions
As the title suggests, how can I tell a JVM thrown exception from a Programmatically(does this mean, thrown by a programmer or the program) thrown exception ?
JVM Exceptions
1) ArrayIndexOutOfBoundsException
2) ClassCastException
3) NullPointerException
Programmatically thrown
1) NumberFormatException
2) AssertionErr开发者_StackOverflowor
Many Thanks
How to differentiate between Programmer and JVM Exceptions
You cannot do this statically because no such distinction exists.
Any exception defined in the standard Java class libraries may be thrown by application or third-party library code. This includes exceptions (including those that you listed) that are normally thrown by the JVM itself.
In some cases, it is a bad (or even terrible) idea to throw a standard exception. For example, it would be a really bad idea for an application to throw something like
VerifyError
because that has a very specific meaning that an application has no business throwing.In other cases, there are no issues. For example, there is no problem1 with an application throwing
NullPointerException
explicitly; e.g.public void setName(String name) { if (name == null) { throw new NullPointerException("name must not be null"); } this.name = name; }
The only possible way to distinguish between an exception that has been thrown by the JVM and by application code is to examine the stack frames from the thrown exception to figure out what class instantiated the exception. (Strictly speaking that doesn't tell you where the exception was thrown ... but it is close enough given that exceptions are nearly always instantiated and thrown in the same statement.)
But even this is not a useful distinction to make. There is no semantically useful difference between an exception thrown by application code, the standard class library or the JVM itself. The source of the exception certainly doesn't say anything about the root cause of the problem; e.g. whether it is due to an application bug, a library bug or something else.
The only useful distinctions are:
- Error exceptions which you should not attempt to recover from, because they are usually not recoverable.
- Other unchecked exceptions which may be recoverable, but are typically caused by bugs.
- Checked exceptions which are often caused by "environmental" problems (such as incorrect file names) that may well need to be reported to the user.
There are a couple of alternative readings of the question:
If you wanted to distinguish the exceptions that could be thrown by the JVM from those that can only be thrown by Java code, you could do this by searching the OpenJDK source code for places where exceptions are thrown from native code.
If you wanted to distinguish the exceptions that could be thrown by the JVM OR by the standard Java libraries, broaden the search to include Java source code.
However, in both cases the "answer" is not useful (as above), and will depend on the particular Java release you examine.
1 - 1) There are no technical problems with throwing NPE, CCE, AIOOBE and so on. 2) I have never come across a style guide that says you shouldn't do it. 3) I have never seen a coherent explanation of why it should be "frowned on". (If you know of one, please provide a link to it.)
I'm not sure what you mean by JVM exceptions. These are all runtime exceptions that may be thrown by the programmer at any point (exception AssertionError
), though it is considered poor style to throw certain exceptions like NullPointerException
. The point is, there's no one quality separating the two categories you mention other than their typical usage. All the runtime exceptions extend, either directly or indirectly, RuntimeException
.
From the JavaDocs for Throwable
:
Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement.
Because this same superclass defines all exceptions thrown by either the JVM or a programmer, you can't easily distinguish the two.
I don't think you will find a complete list, since there is no clear distinction between jvm and programmer initiated exceptions, apart from a few special cases:
- most
Error
classes are thrown by the VM, due to internal or external causes. The one exception ThreadDeath, is thrown in a thread when that thread is stopped, and is kind of a "hack" to get the thread to unwind it's stack and exit. - most checked exceptions relate to environmental problems that lead to failure of some operation, but may be resolvable and are non-fatal to the JVM (IOException, SQLException, RemoteException) come to mind.
- the remainder, unchecked exceptions, are a combination of both jvm and programmer initiated exception. For example, the JDK throws
IllegalArgumentException
when method parameters are not to spec. Is that a JVM exception or a programmatic exception? It unclear if your definition of JVM exceptions includes the JDK or not.ArrayIndexOutOfBounds
is generated for illegal array accesses, generated by the JVM, but it's also thrown in some apis, e.g. Track.get from java.midi. (Although this can be argued as poor form, and the superclassIndexOutOfBounds
should have been used instead.)
The most used exceptions thrown by JVM and by API are:
Exceptions thrown by JVM
- ArrayIndexOutOfBoundsException
- ClassCastException
- NullPointerException
- ArithmeticException
- AssertionError
- ExceptionInInitializerError
- StackOverflowError
- NoClassDefFoundError
Programmatically by API thrown
- llegalArgumentException
- NumberFormatException
- IllegalStateException
- SecurityException
Where exceptions come from
It's important that you understand what causes exceptions and errors and where they come from. Java defines two broad categories of exceptions and errors:
JVM exceptions: those exceptions or errors that are either exclusively or most logically thrown by the JVM
Programmatic exceptions: those exceptions that are thrown explicitly by application and/or API programmers
A very common exception, the NullPointerException
occurs when you attempt to access an object using a reference variable with a current value of null
. There's no way that the compiler can hope to find those problems before runtime. Take a look at the following:
class NPE {
static String s;
public static void main(String [] args) {
System.out.println(s.length());
}
}
精彩评论