Page 1 of 1

About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Tue Jun 17, 2014 2:57 pm
by aleksjej
In exception class summary we can read that the AssertionError is thrown by JVM, not by the programmer explicitly so how is that possible that in the first case AssertionError is better choice than IllegalArgumentException? Thanks

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Tue Jun 17, 2014 8:30 pm
by admin
It is true that AssertionError is thrown by the JVM when an assertion fails. But a programmer can throw it explicitly as well for situations that he assumes will never occur. In this case, he knows that suit can never have any other value, it is therefore appropriate for him to throw AssertionError. It is same as using assert statement in situations where the programmer knows that something will definitely be true.

IllegalArgumentException is thrown by the programmer when he knows that the method may be called with illegal arguments by someone else.

The terminology "thrown by the JVM" and "thrown programatically or by the application" is not precise but is used by popular books. If it helps, you can think of the exception categories as "thrown implicitly" and "thrown explicitly". An exception that is thrown even when there is no throw statement, is said to be thrown implicitly. For example, calling a method on null will cause a NullPointerException to be thrown automatically, even though there is no throw statement. On the other hand, a code may throw an exception explicitly by using the throw statement. For example, a method code might check an argument for validity and if it finds the argument inappropriate, it may throw an exception by executing throw new IllegalArgumentException();.


HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Mon Feb 23, 2015 7:15 pm
by mutley
I understand your answer from a point of view , but I do not find it an absolute answer . Let me explain :
Since that Enum ONLY has 4 elements , would it be wrong to assume that another state would mean an IllegalState of that object?

So why one cannot throw an IllegalStateException ?

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Mon Feb 23, 2015 8:46 pm
by admin
It is a bit subjective and so there is no absolute answer. Yes, you have a valid point for an IllegalStateException. On the other hand, the state of object which contains the given switch statement is not illegal. The state of the suit object is illegal because the suit object contains an extra value for the enum. So from that perspective, IllegalStateException may not be so valid.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 10:54 am
by winddd
Enum can be extended. Throwing AssertionError instead of using assert - unacceptable. Using assert in this situation - unacceptable.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 11:44 am
by admin
winddd wrote:Enum can be extended.
No, they can't be extended (in Java, at least).
Throwing AssertionError instead of using assert - unacceptable. Using assert in this situation - unacceptable.
Perfectly valid because of above.

On a side note, even if you were able to extend an enum, your switch statement wouldn't compile if you had case values not belonging to the enum of your switch variable.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 12:49 pm
by winddd
admin wrote:No, they can't be extended (in Java, at least).
CAN. Teamwork. New enum elements can be added without notice. Programmer always has to consider such opportunity.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 12:52 pm
by winddd
Moreover, raising an exception is admissible in certain cases, it can be both IllegalArgumentException, and IllegalStateException, depending on a context.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 9:09 pm
by admin
Hence the use of assersions. Assertions are used for conditions that the programmer has assumed to hold true. If any such condition changes, it should be found out during development When assertions are enabled. Here, the question clearly mentions that there are no other values in the enum. Therefore, usage of assertion is valid.

By your logic, any code can be changed, so why use assertions at all?

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Feb 25, 2015 9:12 pm
by admin
winddd wrote:Moreover, raising an exception is admissible in certain cases, it can be both IllegalArgumentException, and IllegalStateException, depending on a context.
Not acceptable in this situation because any other value for enum is not possible.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Thu Feb 26, 2015 7:01 pm
by winddd
admin wrote:By your logic, any code can be changed, so why use assertions at all?
correct use of asserts:

Code: Select all

int i = 10 / 2; assert i == 5 : "crazy jvm";
And never raise AssertionError manually.
admin wrote:Not acceptable in this situation because any other value for enum is not possible.
Other values for enum is always possible. Integer > 2147483647 - not possible, String.length() < 0 - not possible. Fixed enum contents - not possible, as it not typical. SomeObject.applyState(stateEnum) throwing AssertionError? SomeObject.executeCommand(stateEnum) throwing AssertionError? It's ridiculous.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Thu Feb 26, 2015 10:54 pm
by admin
I am sorry but I don't agree with your argument. Here is a statement straight from the official oracle's tutorial
Assertions, however, should be used to check for cases that should never happen, check assumptions about data structures (such as ensuring that an array is of the correct length), or enforcing constraints on arguments of private methods.
If you restrict the use of assertions to the kind of cases that you've mentioned i.e. Integer > 2147483647 or String.length() < 0, you are basically just adding redundant useless code. If you can't depend on the fact that an int will not be greater than 2147483647, you might as well pick another JVM or platform altogether.

thank you,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Fri Feb 27, 2015 9:20 am
by winddd
admin wrote:I am sorry but I don't agree with your argument. Here is a statement straight from the official oracle's tutorial
Find though one recommendation to throw AssertionError manually.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Fri Feb 27, 2015 9:29 am
by winddd
Assertions, however, should be used to check for cases that should never happen, check assumptions about data structures (such as ensuring that an array is of the correct length), or enforcing constraints on arguments of private methods.
Exactly. New enum elements - not that case.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Fri Feb 27, 2015 9:20 pm
by admin
I think you are misinterpreting the statement. It doesn't just stop after "check for cases that should never happen". The remaining part gives example that make it clear what they mean. Using assertion to check for int > max int is insane.

It is certainly preferable to use the assert statement instead of explicitly throwing but that is not the point of this question. The point is to check the assumptions about the code using assertions from an exam point of view. Switch statement on an enum itself is not a good practice but that doesn't make the whole question invalid from the exam point of view.

On page 157, Effective Java Second edition gives a similar example, where throwing an AssertionError is appropriate -

Code: Select all

// Switch on an enum to simulate a missing method
public static Operation inverse(Operation op) {
  switch(op) {
    case PLUS: return Operation.MINUS;
    case MINUS: return Operation.PLUS;
    case TIMES: return Operation.DIVIDE;
    case DIVIDE: return Operation.TIMES;
    default: throw new AssertionError("Unknown op: " + op);
  }
}
Anyway, I guess we will have to agree to disagree here.

thank you,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Sat Feb 28, 2015 5:14 pm
by winddd
It is a pity that such examples are published in books, but such code is absolutely invalid. It is the point of view of the java-programmer with fifteen years' experience. In my opinion this question should be overworked to exclude AssertionError.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Jul 29, 2015 3:13 pm
by jayallenloew
enthuware.ocajp.i.v7.2.1030

Good discussion. Here is the truth about this question.

As some have correctly noted, the default case statement will never be entered given the enum as written. It could be compared to:

final int a = 100;
final int b = 1000;
if(a>b) {
// do something
}

As you can see, the if condition will never evaluate to true, the code will never be executed, and so the entire conditional statement is legal but unnecessary.

But giving a switch statement a default case, even when of type enum, is part of defensive programming, and is probably a good idea.

Lastly:
a) Explicitly throwing Error, or any of its subclasses such as AssertionError, is normally a bad idea.
b) Throwing AssertionError in this context is far from a slam-dunk, and can rightly be challenged. This question should be either rewritten or withdrawn.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Wed Jul 29, 2015 8:54 pm
by admin
jayallenloew wrote: As some have correctly noted, the default case statement will never be entered given the enum as written. It could be compared to:

final int a = 100;
final int b = 1000;
if(a>b) {
// do something
}
No, it is not the same. Here, a and b are final. In case of enum, no one prevents you from adding another element to the enum. That is what the default case is meant to prevent against.

Re: About Question enthuware.ocajp.i.v7.2.1030 :

Posted: Sat Aug 29, 2015 4:53 am
by skippy
To quote the javadoc for Error
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. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.
This means that if i had a enum that only had 4 valid cases that is being used in 1000 places and one of those places has an assertion error, it might bring down my whole application if at some point someone adds a new enum and it calls that code. It doesn't matter that just one out of the 1000 requests ever reaches that code, instead of inconveniencing one guy, we'll inconvenience everyone by shutting down the entire application.

I would definitely throw a illegal argument exception in this case.

computeDiscount(CustomerType.WEIRD_GUY) is not a serious problem