Reputation: 4558
I have 2 objects from two different classes sharing an attribute of common type (IpAddress
which contains all information about the subnet as well). Now, IpAddress
is a user define type and I have a function setSecondaryRouter()
which can mutate a property of this type. To make the program run as expected I need an invariant (or 2 invariants really) to hold. This is checked in the function setSecondaryRouter()
. However, I want to set this property secondaryRouter
to be the same in the second object as the first. This kind of implies that the invariant already holds the second time I use setSecondaryRouter()
. Due to this I know that the function will not throw.
The problem is that my compiler "helps" to ensure that I do not have uncaught exceptions by not compiling unless I add a try-catch clause or add a throws declaration the caller function (thus helping to solve a non existing problem). What I want to do is to tell Java that this exception will not be thrown. Compare this with the nothrow
keyword in c++. I know similar questions are already posted, like the following
Is there any standard annotation to indicate nothrow semantics in Java?
But my question differ in that I do not want to add a throw, or try-catch clause to specific exceptions which I know will not be thrown!
Also one of the expressions is an IllegalArgumentException. Can this exception be the reason that I have to handle the exceptions?
Upvotes: 0
Views: 857
Reputation: 48624
It is impossible to prevent a method from throwing exceptions. This is because the JVM may cause a method to throw a VirtualMachineError
at anytime. In particular, a method could throw an OutOfMemoryError
even if it does not directly or indirectly allocate memory itself (using a new
operator). This is not a merely theoretical concern: some concurrent garbage collectors will do this if a garbage collection thread takes too long.
Upvotes: 0
Reputation: 1143
The java.lang.IllegalArgumentException
is a Runtime Exception, so it is not taken into consideration by the compiler.
If the exception is possibly thrown for the first use of setSecondaryRouter()
, you must declare it.
Maybe you could declare a new method cloneFirstRouterToSecondRouter
, something like following, catching your Exceptions.
public void cloneFirstRouterToSecondRouter(){
try{
setSecondaryRouter();
catch(Exception e){
// should never occur
}
}
Upvotes: 1
Reputation: 140299
A distinction must be drawn between checked and unchecked exceptions to answer this question:
If a method does not declare that it throws a checked exception, it cannot throw an exception of that type (or one of its subtypes):
void doSomething() {
throw new Exception(); // Illegal, without throws Exception on doSomething();
}
As such, you know that a checked exception is not thrown by a method if it is not declared throwing that exception.
Checked exceptions are intended to be caught, since they are supposed to indicate conditions from which you can recover, so you need to know that they occurred. e.g. IOException
: if you try again later, the file might exist, the disk might have space on it, the network might be back up (etc).
A method can throw an unchecked exception without declaring that it does; but similarly, you don't need to put in any work to catch it if you don't want to (e.g. because you know that it cannot possibly be thrown). As such, you can never guarantee that a particular RuntimeException
is not thrown by a method - maybe it's not thrown directly by the method you called, but it could be thrown by a method that calls (now or in future implementations).
Unchecked exceptions are not really intended to be caught, since they are supposed to indicate unrecoverable errors, like programming errors. e.g. NullPointerException
: you can call the same method with the same parameters, but it'll still fail, because you're running the same code.
Upvotes: 2