From: Rhino on

"Jean-Baptiste Nizet" <jnizetNOSPAM(a)NOSPAMfree.fr> wrote in message
news:4c0121cc$0$17326$426a74cc(a)news.free.fr...
> Rhino a �crit :
>>> I would seriously consider instead of the enum to have a boolean
>>> plus a String, because true/false and a textual explanation is
>>> really what you need.
>>>
>> Sorry, I meant to comment on this point too and didn't realize I had
>> missed it right away....
>>
>> My little PadResult class started out with a boolean and a string with
>> the boolean indicating success or failure of the method and the string
>> containing either an error message or the padded version of the input
>> string. But when I looked at the invocation of PadResult and saw
>>
>> PadResult padResult = new PadResult(true, paddedString);
>>
>> or
>>
>> PadResult padResult = new PadResult(false, errorMsg);
>>
>> I found myself a bit challenged to remember if "true" meant "true, the
>> method produced a good result" or "true, the method found an error". I
>> could probably just memorize that true means a successful result or use
>> some boolean constants to make it clearer - see the example below - but I
>> thought it would be clearer still if I used a well-named enum value so I
>> went with the enum.
>
> When a constructor's argument are not sufficiently clear, it might be a
> good idea to use a factory method instead:
>
> public class PadResult {
>
> private String result;
> private String errorMessage;
> private boolean successful;
>
> private PadResult(boolean successful, String resultOrErrorMessage) {
> this.successful = successful;
> if (successful) {
> this.result = resultOrErrorMessage;
> }
> else {
> this.errorMessage = resultOrErrorMessage;
> }
> }
>
> public static PadResult createSuccessfulResult(String result) {
> return new PadResult(true, result);
> }
>
> public static PadResult createFailedResult(String errorMessage) {
> return new PadResult(false, errorMessage);
> }
>
> // getters omitted
> }
>
> then your pad() method uses
>
> return PadResult.createSuccessfulResult(result);
> or
> return PadResult.createFailedResult(errorMessage);
>
> and it's much clearer.
>

I was starting to think along those lines myself before I saw your post but
was toying with a different approach: one constructor for a successful
result and a different constructor for a problem. I haven't actually tried
writing the code yet to see how much I liked it.

I appreciate your suggestion as another alternative. It looks like it should
work!

Thank you!

--
Rhino


From: Lew on
Rhino wrote:
> There seems to be a considerably body of opinion that Exceptions are
> overkill for relatively minor things like bad input parameters and that they
> should be reserved for more severe problems.

The dichotomy is not between "minor" and "severe" but between "in band" and
"out of band".

You misconstrue if you think that there is a "minor" or "severe" "problem".

The design decision, and the point of divergence of opinion, is what
constitutes "in" or "out of" band.

If you design that bad inputs are "in band", bad input won't throw an exception.
If you design that bad inputs are "out of band", bad input will throw an
exception. Then you decide between checked and runtime exceptions.

The degree to which the exception propagates, and the decision about in or out
of band, depend in part on how low-level the routine in question is.

There are different strategies for logging, too.

As long as you ask the good questions, e.g., "Is bad input in band or out of
band?", you'll tend make good decisions either way. Bad questions, "Is bad
input minor or severe?", tend to lead to bad decisions either way.

--
Lew
From: Rhino on

"Arne Vajh�j" <arne(a)vajhoej.dk> wrote in message
news:4c006f2d$0$278$14726298(a)news.sunsite.dk...
> On 28-05-2010 20:43, Rhino wrote:
>> "Arne Vajh�j"<arne(a)vajhoej.dk> wrote in message
>> news:4c005ae9$0$281$14726298(a)news.sunsite.dk...
>>> On 28-05-2010 19:02, Rhino wrote:
>>>> It's the if statement that concerns me here. This code works fine (I
>>>> can
>>>> test for CompletionStatus.NO_ERROR by simply changlng the right side of
>>>> the
>>>> if) but it doesn't look right. It reminds me of mistakes I made when I
>>>> was
>>>> new to Java comparing Strings to each other via the == operator to see
>>>> if
>>>> they had the same VALUE but discovering that == doesn't determine
>>>> equality
>>>> of value.
>>>
>>>> Is there a better way to do this if statement? If so, what is it?
>>>
>>> I would compare with CompletionStatus.NO_ERROR, because it is
>>> a lot more likely that you will have more than one error status
>>> than more than one no error status.
>>>
>> Okay, that's fair. But am I writing the comparison correctly? That ==
>> operator looks wrong somehow, even if it works. I'm concerned that this
>> might be like comparing two Strings with the == operator; sometimes it
>> will
>> show equality and make you think it is confirming equality of value
>> between
>> the two strings but it is not; you have to use equals() to compare String
>> values. But I'm not sure what the equivalent is for an enum.
>
> == on enums are fine.
>
> Object identity is exactly what is needed.
>

Thank you, Arne! I wasn't able to find that idiom anywhere I looked so it's
good to hear I got it right although I expect that was more luck than brains
;-)

By the way, WHERE is that documented? The Enum class in the Java API
includes an equal() method and the tutorials I read about enum and the Sun
site don't mention that idiom at all...

--
Rhino


From: Lew on
Rhino wrote:
>>>> But am I writing the comparison correctly? That ==
>>>> operator looks wrong somehow, even if it works. I'm concerned that this
>>>> might be like comparing two Strings with the == operator; sometimes it
>>>> will
>>>> show equality and make you think it is confirming equality of value
>>>> between
>>>> the two strings but it is not; you have to use equals() to compare
>>>> String
>>>> values. But I'm not sure what the equivalent is for an enum.

Lew wrote:
>> This is fully covered in the docs for enums, ...

Rhino wrote:

> In fact, I _did_ read some Java articles on enums and they did NOT mention
> that the == operator was the correct one to use.

By "the docs" I'm referring to the JLS and the Javadocs, which are the primary
sources. They don't quite cover everything, but they are canonical as far as
they go.

To whit, the chapter of the language spec that actually defines enums:
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9>
says, in paragraph 2 of the first "Discussion" sidebar,

"Because there is only one instance of each enum constant, it is permissible
to use the == operator in place of the equals method when comparing two object
references if it is known that at least one of them refers to an enum
constant. (The equals method in Enum is a final method that merely invokes
super.equals on its argument and returns the result, thus performing an
identity comparison.)"

--
Lew
From: Lew on
Arne Vajhøj wrote:
>> == on enums are fine.
>>
>> Object identity is exactly what is needed.

Rhino wrote:
> Thank you, Arne! I wasn't able to find that idiom anywhere I looked so it's
> good to hear I got it right although I expect that was more luck than brains
> ;-)
>
> By the way, WHERE is that documented? The Enum class in the Java API
> includes an equal() method

Yes, it does, and if you read the docs there you find:
public final boolean equals(Object other)
telling you that it cannot be overridden and that it "returns true if the
specified object is equal to this enum constant."

From the definition of what an enum is in the language, you know that there
can only be one instance of an enum constant. Ergo, the only way that an
enum's 'equals()' method can return 'true' is if object identity holds, and
therefore the enum's 'equals()' method is functionally equivalent to '=='.

Even without that, you know that the 'equals()' method is safe to use.

--
Lew