Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #38646 > unrolled thread
| Started by | Rhino <no_offline_contact@example.com> |
|---|---|
| First post | 2018-10-24 17:04 -0400 |
| Last post | 2018-10-25 16:07 -0400 |
| Articles | 20 on this page of 29 — 6 participants |
Back to article view | Back to comp.lang.java.programmer
Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-24 17:04 -0400
Re: Overloading methods question Arne Vajhøj <arne@vajhoej.dk> - 2018-10-24 18:56 -0400
Re: Overloading methods question Joerg Meier <joergmmeier@arcor.de> - 2018-10-25 10:13 +0200
Re: Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-25 15:53 -0400
Re: Overloading methods question Eric Douglas <e.d.programmer@gmail.com> - 2018-10-25 13:58 -0700
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-25 17:49 -0400
Re: Overloading methods question Martin Gregorie <martin@mydomain.invalid> - 2018-10-25 22:29 +0000
Re: Overloading methods question Arne Vajhøj <arne@vajhoej.dk> - 2018-10-25 20:08 -0400
Re: Overloading methods question Martin Gregorie <martin@mydomain.invalid> - 2018-10-26 00:37 +0000
Re: Overloading methods question Arne Vajhøj <arne@vajhoej.dk> - 2018-10-25 21:42 -0400
Re: Overloading methods question Joerg Meier <joergmmeier@arcor.de> - 2018-10-26 12:46 +0200
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-26 07:50 -0400
Re: Overloading methods question Martin Gregorie <martin@mydomain.invalid> - 2018-10-26 19:33 +0000
Re: Overloading methods question Eric Douglas <e.d.programmer@gmail.com> - 2018-10-26 13:13 -0700
Re: Overloading methods question Arne Vajhøj <arne@vajhoej.dk> - 2018-10-26 20:58 -0400
Re: Overloading methods question Martin Gregorie <martin@mydomain.invalid> - 2018-10-27 22:36 +0000
Re: Overloading methods question Arne Vajhøj <arne@vajhoej.dk> - 2018-10-27 19:38 -0400
Re: Overloading methods question Martin Gregorie <martin@mydomain.invalid> - 2018-10-28 10:39 +0000
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-28 07:54 -0400
Re: Overloading methods question Eric Douglas <e.d.programmer@gmail.com> - 2018-10-26 06:26 -0700
Re: Overloading methods question Joerg Meier <joergmmeier@arcor.de> - 2018-10-26 12:52 +0200
Re: Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-26 22:10 -0400
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-27 07:43 -0400
Re: Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-29 14:40 -0400
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-29 16:39 -0400
Re: Overloading methods question Eric Douglas <e.d.programmer@gmail.com> - 2018-10-29 05:07 -0700
Re: Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-29 14:41 -0400
Re: Overloading methods question Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-10-25 07:49 -0400
Re: Overloading methods question Rhino <no_offline_contact@example.com> - 2018-10-25 16:07 -0400
Page 1 of 2 [1] 2 Next page →
| From | Rhino <no_offline_contact@example.com> |
|---|---|
| Date | 2018-10-24 17:04 -0400 |
| Subject | Overloading methods question |
| Message-ID | <pqqmoq$jeo$1@dont-email.me> |
Is it better to overload a single method name several times or to create uniquely-named methods to accomplish similar work? I am in the midst of rewriting some old convenience methods that work with dates and times but use the old Calendar and java.util.Time classes. I know that it is far better to use the java.time.* packages now. In the course of revising my methods to use the Java 8 classes, it has occurred to me that I should have several variants of some of the methods. For instance, one of my methods determines the name of the current month. It seems reasonable to me that I might at some point need to know the name of the current month: - in either short or long version - i.e. "Oct" or "October" - in the local timezone or a different one (after all, while it may be late in the day on Oct 31 in my timezone, it may already be early Nov 1 a few timezones away) APPROACH 1: I could have several overloaded versions of a single method. For instance: - getCurrentMonthName(boolean fullMonthName) and assume local time zone - getCurrentMonthName(ZoneId zoneId) and assume full month name - getCurrentMonthName(boolean fullMonthName, ZoneId zoneId) and assume nothing - getCurrentMonthName() and assume local time zone and full month name APPROACH 2: Or I could do this: - getCurrentMonthNameLocal(boolean fullMonthName) and assume local time zone - getCurrentMonthNameRemote(boolean fullMonthName, ZoneId zoneId) and assume nothing APPROACH 3: I could even do this: - getCurrentMonthNameFullLocal() and assume local time zone - getCurrentMonthNameShortLocal() and assume local time zone - getCurrentMonthNameFullRemote(ZoneId zoneId) and use specified time zone - getCurrentMonthNameShortRemote(ZoneId zoneId) and use specified time zone APPROACH 4: Or I could reduce the number of methods I need by having only this: - getCurrentMonthName(boolean fullMonthName, ZoneId) which would force users to supply a value for the boolean and the zoneId every time even if they wanted the local time zone Which is the best design and, most importantly, WHY? I expect there is a basic design precept somewhere that helps a developer decide which is the best way to go in circumstances like these. It would be helpful to learn (or rediscover) this principle. Can anyone help me out? In the absence of such a principle, it seems to me that I need to weigh the costs of each approach against the benefits and see which is the best balance. For instance, Approach 4 has the benefit of requiring me to code only one method to get the current month but means the method is more complex and probably has more conditions to test in unit test. It may also be more work for the person trying to use these classes as they have to understand the meaning of the parameters and figure out how to set the desired values. (I'm just learning the Java 8 time classes and didn't know what a zoneId was 24 hours ago, let alone how to set it and what values I could use. A developer using these classes might be in the same boat.) -- Rhino
[toc] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2018-10-24 18:56 -0400 |
| Message-ID | <pqqtbi$lr$1@gioia.aioe.org> |
| In reply to | #38646 |
On 10/24/2018 5:04 PM, Rhino wrote: > Is it better to overload a single method name several times or to create > uniquely-named methods to accomplish similar work? > It seems reasonable to me that I might at some point need to know the > name of the current month: > - in either short or long version - i.e. "Oct" or "October" > - in the local timezone or a different one (after all, while it may be > late in the day on Oct 31 in my timezone, it may already be early Nov 1 > a few timezones away) > > APPROACH 1: > I could have several overloaded versions of a single method. For instance: > - getCurrentMonthName(boolean fullMonthName) and assume local time zone > - getCurrentMonthName(ZoneId zoneId) and assume full month name > - getCurrentMonthName(boolean fullMonthName, ZoneId zoneId) and assume > nothing > - getCurrentMonthName() and assume local time zone and full month name > > APPROACH 2: > Or I could do this: > - getCurrentMonthNameLocal(boolean fullMonthName) and assume local time > zone > - getCurrentMonthNameRemote(boolean fullMonthName, ZoneId zoneId) > and assume nothing > > APPROACH 3: > I could even do this: > - getCurrentMonthNameFullLocal() and assume local time zone > - getCurrentMonthNameShortLocal() and assume local time zone > - getCurrentMonthNameFullRemote(ZoneId zoneId) and use specified time zone > - getCurrentMonthNameShortRemote(ZoneId zoneId) and use specified time zone > > APPROACH 4: > Or I could reduce the number of methods I need by having only this: > - getCurrentMonthName(boolean fullMonthName, ZoneId) which would force > users to supply a value for the boolean and the zoneId every time even > if they wanted the local time zone > > Which is the best design and, most importantly, WHY? I expect there is a > basic design precept somewhere that helps a developer decide which is > the best way to go in circumstances like these. It would be helpful to > learn (or rediscover) this principle. I would go for approach #5: getCurrentMonth(boolean fullMonthName) getCurrentMonth(boolean fullMonthName, ZoneId zoneId) My logic: * I expect the method name in a get to explain what it is getting and any arguments to qualify how it should be getting it and that points to #2 and * and ZoneId is sufficient rare to warrant a default value and since Java does not have defaults that means an overload Arne
[toc] | [prev] | [next] | [standalone]
| From | Joerg Meier <joergmmeier@arcor.de> |
|---|---|
| Date | 2018-10-25 10:13 +0200 |
| Message-ID | <1b2bqd7oqzez6$.sfpve8lwmic2.dlg@40tude.net> |
| In reply to | #38646 |
On Wed, 24 Oct 2018 17:04:27 -0400, Rhino wrote:
> Is it better to overload a single method name several times or to create
> uniquely-named methods to accomplish similar work?
I would argue that you should overload methods that return the same thing,
but have separate methods for returning different things. In that spirit, I
would overload the methods with an without a zone, but have separate
methods for gettting the full name, as I suspect from your posting that
those do in fact return something different.
That being said, while this was probably just an example, I should point
out that this is generally the completely wrong approach and kind of
violates sensible object oriented design: return the month instead, and let
the caller ask the month what it's called. That's what java.time.Month is
for.
Liebe Gruesse,
Joerg
--
"Immer wieder erstaunlich, wie lächerlich man sich doch machen kann und
sich dabei noch toll finden."
- Hartmut Kraus, 19.3.2017 in de.soc.recht.misc
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.
[toc] | [prev] | [next] | [standalone]
| From | Rhino <no_offline_contact@example.com> |
|---|---|
| Date | 2018-10-25 15:53 -0400 |
| Message-ID | <pqt6v0$e65$1@dont-email.me> |
| In reply to | #38648 |
On 2018-10-25 4:13 AM, Joerg Meier wrote:
> On Wed, 24 Oct 2018 17:04:27 -0400, Rhino wrote:
>
>> Is it better to overload a single method name several times or to create
>> uniquely-named methods to accomplish similar work?
>
> I would argue that you should overload methods that return the same thing,
> but have separate methods for returning different things. In that spirit, I
> would overload the methods with an without a zone, but have separate
> methods for gettting the full name, as I suspect from your posting that
> those do in fact return something different.
>
> That being said, while this was probably just an example, I should point
> out that this is generally the completely wrong approach and kind of
> violates sensible object oriented design: return the month instead, and let
> the caller ask the month what it's called. That's what java.time.Month is
> for.
>
Actually, it was a "real life example". That is one of the methods I am
rewriting
in my class of convenience methods.
I was intrigued by your suggestion that I should just return the month
and let the caller ask the month what it is called. I wasn't sure what
you mean by that. but I wrote a bit of code and came up with this:
static java.time.Month getCurrentMonth() {
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
return zdt.getMonth();
}
Then, in the code which calls the convenience method, something like this:
String fullMonthName =
CurrentDateTimeUtils.getCurrentMonth().getDisplayName(TextStyle.FULL,
new Locale("de", "DE"))); //gets full month name in German e.g. Oktober
String shortMonthName =
CurrentDateTimeUtils.getCurrentMonth().getDisplayName(TextStyle.SHORT,
new Locale("de", "DE"))); //gets short month name in German e.g. Okt.
int numericMonth = CurrentDateTimeUtils.getCurrentMonth().getValue();
//gets numeric value of month e.g. 10 for October
Or did you have something different in mind?
I rather like the approach you're suggesting. If I give the
responsibility of deciding which version of the month name people want
back to the calling program, that simplifies my convenience class so
that I need fewer methods while leaving it entirely possible for the
calling program to get the month information in any format it likes
since all the possible formats can be derived from what the convenience
method returns.
Either way, the program using my convenience method has to decide what
it wants - and will get what it wants - so it's very reasonable to
design the convenience class the way you suggest.
--
Rhino
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2018-10-25 13:58 -0700 |
| Message-ID | <75ad8b55-3def-4ec1-b46b-65ecd971d0fe@googlegroups.com> |
| In reply to | #38650 |
On Thursday, October 25, 2018 at 3:53:15 PM UTC-4, Rhino wrote:
> static java.time.Month getCurrentMonth() {
>
> LocalDateTime ldt = LocalDateTime.now();
> ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
>
> return zdt.getMonth();
> }
>
> Then, in the code which calls the convenience method, something like this:
>
> String fullMonthName =
> CurrentDateTimeUtils.getCurrentMonth().getDisplayName(TextStyle.FULL,
> new Locale("de", "DE"))); //gets full month name in German e.g. Oktober
> String shortMonthName =
> CurrentDateTimeUtils.getCurrentMonth().getDisplayName(TextStyle.SHORT,
> new Locale("de", "DE"))); //gets short month name in German e.g. Okt.
> int numericMonth = CurrentDateTimeUtils.getCurrentMonth().getValue();
> //gets numeric value of month e.g. 10 for October
>
> Or did you have something different in mind?
>
> I rather like the approach you're suggesting. If I give the
> responsibility of deciding which version of the month name people want
> back to the calling program, that simplifies my convenience class so
> that I need fewer methods while leaving it entirely possible for the
> calling program to get the month information in any format it likes
> since all the possible formats can be derived from what the convenience
> method returns.
>
> Either way, the program using my convenience method has to decide what
> it wants - and will get what it wants - so it's very reasonable to
> design the convenience class the way you suggest.
>
>
> --
> Rhino
Yes, that looks right. The key to overload is the return value. Use the same exact method name and add parameters if you're returning the same value. Use boolean where there are exactly 2 possibilities (print duplex? yes or no). Use enums where there could be more than 2 possibilities or the parameter itself is simply not clear. You can have the method return the month in formatted string if one of your parameters accepts an enum to tell it which format. In this particular case returning the month object from the java time class makes sense if it already has enums to tell it how to format.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2018-10-25 17:49 -0400 |
| Message-ID | <pqtdpa$nl4$1@dont-email.me> |
| In reply to | #38652 |
On 10/25/2018 4:58 PM, Eric Douglas wrote:
> [...]
> Use boolean where there are exactly 2 possibilities (print duplex? yes or no). [...]
Use booleans where there exactly two possibilities *and* where
their associations with `true' and `false' are flat-out obvious.
/** An old-fashioned binary-gendered person. */
public class Person {
/** A poorly-designed constructor API. */
public Person(Name name, boolean gender) {
...
Things would be a little bit better if `gender' were renamed to
`isMale' or `isFemale', but even with the improvement it's not great:
Person flawedSage = new Person(new Name("Kao", "Li"), false);
... is not especially transparent.
Also, be careful to distinguish between "there are exactly two
possibilities" and "I have thought of only two possibilities." It
is perhaps instructive that the example given would not work for the
printer that sits on my desk at this moment, which has *five* modes
for duplexing:
One-sided
Two-sided (automatic, flip on long axis)
Two-sided (automatic, flip on short axis)
Two-sided (manual, flip on long axis)
Two-sided (manual, flip on short axis)
(In the "automatic" modes the printer marks one side but doesn't
spit the page out, then sucks it back in and does the second side.
In the "manual" modes it prints and ejects all the back sides, then
you re-insert the stack in the paper supply and it prints the formerly-
blank fronts. "Automatic" is more convenient, "Manual" can be faster
for long documents.)
Duplex-or-not is, as suggested, a Yes/No question -- but if the
answer is Yes the answer is incomplete, lacking essential detail.
A good API offers (relatively) straightforward ways to supply all
the necessary information.
--
esosman@comcast-dot-net.invalid
Eight hundred nineteen days to go.
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@mydomain.invalid> |
|---|---|
| Date | 2018-10-25 22:29 +0000 |
| Message-ID | <pqtg50$ga7$1@news.albasani.net> |
| In reply to | #38653 |
On Thu, 25 Oct 2018 17:49:28 -0400, Eric Sosman wrote:
> On 10/25/2018 4:58 PM, Eric Douglas wrote:
>> [...]
>> Use boolean where there are exactly 2 possibilities (print duplex? yes
>> or no). [...]
>
> Use booleans where there exactly two possibilities *and* where
> their associations with `true' and `false' are flat-out obvious.
>
> /** An old-fashioned binary-gendered person. */
> public class Person {
> /** A poorly-designed constructor API. */ public Person(Name
name,
> boolean gender) {
> ...
>
> Things would be a little bit better if `gender' were renamed to
> `isMale' or `isFemale', but even with the improvement it's not great:
>
> Person flawedSage = new Person(new Name("Kao", "Li"), false);
>
> ... is not especially transparent.
>
In those circumstances I tend to define constants in the consuming class.
In the OP's case I'd probably change the boolean to an int named
nameFormat and declare the constants:
public static final int LONG 1;
public static final int SHORT 2;
and my code in the class would also use the SHORT and LONG constants
because:
(a) this way I don't have to create an enum and the javadocs will
document the values automatically
(b) both the method call and the internal code are easy to read
(c) the constant values have no hidden uses so the actual values used
don't matter as long as they're different
(d) if additional values are needed in future they're easy to add
I realise that this approach probably betrays my C background, but is
anything else about it wrong enough that it should cause me to use enums
instead?
--
Martin | martin at
Gregorie | gregorie dot org
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2018-10-25 20:08 -0400 |
| Message-ID | <pqtluk$gg9$1@gioia.aioe.org> |
| In reply to | #38654 |
On 10/25/2018 6:29 PM, Martin Gregorie wrote: > In those circumstances I tend to define constants in the consuming class. > In the OP's case I'd probably change the boolean to an int named > nameFormat and declare the constants: > > public static final int LONG 1; > public static final int SHORT 2; > > and my code in the class would also use the SHORT and LONG constants > because: > > (a) this way I don't have to create an enum and the javadocs will > document the values automatically > (b) both the method call and the internal code are easy to read > (c) the constant values have no hidden uses so the actual values used > don't matter as long as they're different > (d) if additional values are needed in future they're easy to add > > I realise that this approach probably betrays my C background, but is > anything else about it wrong enough that it should cause me to use enums > instead? Enum achives the same 4 goals (except obviously the first half of #a - not having to define an enum). And enum will be better/easier documented for method arguments. And enum is type safe while int constants are not. foobar(7 * LONG + SHORT); will be accepted by the compiler but have undefined semantics. Arne
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@mydomain.invalid> |
|---|---|
| Date | 2018-10-26 00:37 +0000 |
| Message-ID | <pqtnjm$abo$1@news.albasani.net> |
| In reply to | #38655 |
On Thu, 25 Oct 2018 20:08:54 -0400, Arne Vajhøj wrote: > Enum achives the same 4 goals (except obviously the first half of #a - > not having to define an enum). > Sure, though being defined outside a class that is the only place its used (apart from when its supplied as a method argument) as we've been discussing does separate each constant definition and its documentation from the class definition and documentation > And enum will be better/easier documented for method arguments. > Apart from the separation mentioned above. I see this as a disadvantage though you may not. > And enum is type safe while int constants are not. > AFAIK that is not relevant if the constant is defined as static final. > will be accepted by the compiler but have undefined semantics. > Agreed, but being basically a mildly paranoid C programmer I tend to validate all arguments, including those created with a #define (C) or as static final int (Java) and you really shouldn't be defining a constant unless its one of the above or part of an enum. So far, it all looks a bit like swings and roundabouts to me except, of course, if your enum contains logic rather than being simply a list of constants. -- Martin | martin at Gregorie | gregorie dot org
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2018-10-25 21:42 -0400 |
| Message-ID | <pqtrdv$mu8$1@gioia.aioe.org> |
| In reply to | #38656 |
On 10/25/2018 8:37 PM, Martin Gregorie wrote: > On Thu, 25 Oct 2018 20:08:54 -0400, Arne Vajhøj wrote: >> Enum achives the same 4 goals (except obviously the first half of #a - >> not having to define an enum). >> > Sure, though being defined outside a class that is the only place its > used (apart from when its supplied as a method argument) as we've been > discussing does separate each constant definition and its documentation > from the class definition and documentation I am not sure that I can follow that argument. If you make the enum nested instead of top level then it will be in the same source file at the same place as the int constants would have been. And in the java docs you just click on the type to get to the java docs instead of scrolling around searching for info you need. >> And enum will be better/easier documented for method arguments. >> > Apart from the separation mentioned above. I see this as a disadvantage > though you may not. public void foobar(MyEnum val) is simpler than: /** * ... * Note: val takes the values SomeClass.Const1, ..., SomeClass.Constn */ public void foobar(int val) >> And enum is type safe while int constants are not. >> > AFAIK that is not relevant if the constant is defined as static final. It is as the example shown. >> will be accepted by the compiler but have undefined semantics. >> > Agreed, but being basically a mildly paranoid C programmer I tend to > validate all arguments, including those created with a #define (C) or as > static final int (Java) and you really shouldn't be defining a constant > unless its one of the above or part of an enum. Yes. But that is a runtime error instead of a compile time error. Moving errors from runtime to compile time is what type safety is all about. And many people (but not all) consider doing that a good thing. Arne
[toc] | [prev] | [next] | [standalone]
| From | Joerg Meier <joergmmeier@arcor.de> |
|---|---|
| Date | 2018-10-26 12:46 +0200 |
| Message-ID | <16nzai1tzrp1d.4yh8ynprin5c$.dlg@40tude.net> |
| In reply to | #38656 |
On Fri, 26 Oct 2018 00:37:10 +0000 (UTC), Martin Gregorie wrote:
>> And enum is type safe while int constants are not.
> AFAIK that is not relevant if the constant is defined as static final.
martinsMethod(BoxLayout.X_AXIS); // what now ?
The above may work, or not work, or change what it does between Java
versions, and will not be detected during compile time. I know it looks too
obvious to get wrong, and in this example it is, but once you start having
people copy and paste code around and extract parameters to variables and
fields, it becomes less obvious that there is a problem here.
If you feel the above example is too contrived:
foo(boolean bigDesign) {
int designSetting1;
int designSetting2;
if (bigDesign) {
designSetting1 = BoxLayout.X_AXIS;
designSetting2 = MartinsClass.LONG;
} else {
designSetting1 = BoxLayout.Y_AXIS;
designSetting2 = MartinsClass.SHORT;
}
// ...
// ...
// ...
// ...
// ...
// ...
doSomething(martinsClass(designSetting1));
}
Liebe Gruesse,
Joerg
--
"Immer wieder erstaunlich, wie lächerlich man sich doch machen kann und
sich dabei noch toll finden."
- Hartmut Kraus, 19.3.2017 in de.soc.recht.misc
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2018-10-26 07:50 -0400 |
| Message-ID | <pquv2d$6p2$1@dont-email.me> |
| In reply to | #38656 |
On 10/25/2018 8:37 PM, Martin Gregorie wrote:
> On Thu, 25 Oct 2018 20:08:54 -0400, Arne Vajhøj wrote:
>
>> Enum achives the same 4 goals (except obviously the first half of #a -
>> not having to define an enum).
>>
> Sure, though being defined outside a class that is the only place its
> used (apart from when its supplied as a method argument) as we've been
> discussing does separate each constant definition and its documentation
> from the class definition and documentation
public class Whatnot {
public static enum Style { LONG, SHORT };
...
String method(Style style) { ... }
}
Whatnot what = new Whatnot();
String thing = what.method(Whatnot.Style.SHORT);
>> And enum will be better/easier documented for method arguments.
>>
> Apart from the separation mentioned above. I see this as a disadvantage
> though you may not.
"Better/easier" is a *dis*advantage? Is this Opposite Day?
>> And enum is type safe while int constants are not.
>>
> AFAIK that is not relevant if the constant is defined as static final.
Both Arne's and Martin's comments elude my understanding, so
I won't try to respond.
>> will be accepted by the compiler but have undefined semantics.
>>
> Agreed, but being basically a mildly paranoid C programmer I tend to
> validate all arguments, including those created with a #define (C) or as
> static final int (Java) and you really shouldn't be defining a constant
> unless its one of the above or part of an enum.
Early mistake detection beats late misteak detectoin, every time.
Compile-time detection beats run-time detection.
> So far, it all looks a bit like swings and roundabouts to me except, of
> course, if your enum contains logic rather than being simply a list of
> constants.
My scorecard shows Arne with three, Martin with nil, and one
undecided.
--
esosman@comcast-dot-net.invalid
Eight hundred seventeen days to go.
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@mydomain.invalid> |
|---|---|
| Date | 2018-10-26 19:33 +0000 |
| Message-ID | <pqvq6t$cah$1@news.albasani.net> |
| In reply to | #38660 |
On Fri, 26 Oct 2018 07:50:34 -0400, Eric Sosman wrote: > My scorecard shows Arne with three, Martin with nil, and one > undecided. > Fair enough. General ignorance of Enums is why I asked and I've learnt stuff from as a result. I haven't (so far) used Enums and it wasn't obvious from the tutorial stuff that you can put a public Enum inside a class - rather the opposite in fact, since at one point it said that an enum declaration was at a similar language level to a class declaration, which is why I thought it could not be declared insire a class definition. Thanks to Eric's example I now see that was an incorrect assumption: I'll use Enums that way in future: my main background is Assembler/COBOL/C in that order, so of course I instantly saw the equivalence between #define SHORT 1 or its assembler equivalent and public static final int ONE = 1; -- Martin | martin at Gregorie | gregorie dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2018-10-26 13:13 -0700 |
| Message-ID | <7f0c5b7c-1c0d-4691-93bc-1a33942eefa1@googlegroups.com> |
| In reply to | #38662 |
On Friday, October 26, 2018 at 3:34:00 PM UTC-4, Martin Gregorie wrote:
> On Fri, 26 Oct 2018 07:50:34 -0400, Eric Sosman wrote:
>
> > My scorecard shows Arne with three, Martin with nil, and one
> > undecided.
> >
> Fair enough. General ignorance of Enums is why I asked and I've learnt
> stuff from as a result.
>
> I haven't (so far) used Enums and it wasn't obvious from the tutorial
> stuff that you can put a public Enum inside a class - rather the opposite
> in fact, since at one point it said that an enum declaration was at a
> similar language level to a class declaration, which is why I thought it
> could not be declared insire a class definition.
>
> Thanks to Eric's example I now see that was an incorrect assumption: I'll
> use Enums that way in future: my main background is Assembler/COBOL/C in
> that order, so of course I instantly saw the equivalence between
>
> #define SHORT 1 or its assembler equivalent
>
> and
>
> public static final int ONE = 1;
>
Aye, it's literally that simple. Most of my values are also just on public static final int because I wrote most of the API before enum was a thing, but my one enum looks like this.
public class MyInputControl extends JTextField {
public static enum INPUT_STYLE {
CHARACTER, DATE, NUMBER,
}
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2018-10-26 20:58 -0400 |
| Message-ID | <pr0d83$r6t$1@gioia.aioe.org> |
| In reply to | #38662 |
On 10/26/2018 3:33 PM, Martin Gregorie wrote:
> I haven't (so far) used Enums and it wasn't obvious from the tutorial
> stuff that you can put a public Enum inside a class - rather the opposite
> in fact, since at one point it said that an enum declaration was at a
> similar language level to a class declaration,
It is.
> which is why I thought it
> could not be declared insire a class definition.
You can put a class declaration inside a class.
> I'll
> use Enums that way in future: my main background is Assembler/COBOL/C in
> that order, so of course I instantly saw the equivalence between
>
> #define SHORT 1 or its assembler equivalent
>
> and
>
> public static final int ONE = 1;
I will say that:
C Java
#define X 1 No equivalent
#define Y 2
#define Z 3
const int X = 1; public static final int X = 1;
const int Y = 2; public static final int Y = 2;
const int Z = 3; public static final int Z = 3;
enum XYZ { X, Y, Z }; public enum XYZ { X, Y, Z }
Assuming ANSI C and Java >= 1.5.
Arne
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@mydomain.invalid> |
|---|---|
| Date | 2018-10-27 22:36 +0000 |
| Message-ID | <pr2pa5$sql$1@news.albasani.net> |
| In reply to | #38664 |
On Fri, 26 Oct 2018 20:58:44 -0400, Arne Vajhøj wrote:
> On 10/26/2018 3:33 PM, Martin Gregorie wrote:
>> I haven't (so far) used Enums and it wasn't obvious from the tutorial
>> stuff that you can put a public Enum inside a class - rather the
>> opposite in fact, since at one point it said that an enum declaration
>> was at a similar language level to a class declaration,
>
> It is.
>
>> which is why I thought it
>> could not be declared inside a class definition.
>
> You can put a class declaration inside a class.
>
Yes indeed, but as I found out it seems not so simple to access it from
outside. The following shows how I wanted to declare and use a enum, i.e.
as a direct a replacement for the set of public static final ints).
Here's an SSCCE that shows the problem.
public class EnumWrapper
{
public enum MyEnum { ONE, TOO, TREE };
public static void main(String args[])
{
for (MyEnum x: MyEnum.values())
printVal(x);
}
public static void printVal(MyEnum v)
{
System.out.println("printval(" + v + ")");
}
}
This works as expected with the enum used inside its declaring class:
$ java EnumWrapper
printval(ONE)
printval(TOO)
printval(TREE)
BUT, I also want to use it as a parameter when calling a methods in the
class where the enum is declared, IOW exactly how I'd use a public static
final int declared in the class:
public class TestRun
{
public static void main(String args[])
{
EnumWrapper ew = new EnumWrapper();
ew.printval(MyEnum.ONE);
}
}
... and this won't compile:
This works as expected if the enum is being used inside its declaring
class:
$ javac TestRun.java
TestRun.java:7: error: cannot find symbol
ew.printval(MyEnum.ONE);
^
symbol: variable MyEnum
location: class TestRun
1 error
and, if I replace 'MyEnum' with "EnumWrapper", the name of the class,
it still fails to compile:
$ javac TestRun.java
TestRun.java:7: error: cannot find symbol
ew.printval(EnumWrapper.ONE);
^
symbol: variable ONE
location: class EnumWrapper
1 error
Moving the enum to a separate file containing nothing except a package
name specifier and the public enum declaration obviously works, but is
not what I want since it separates the constants in the declaration from
the code that accepts them as method arguments.
I understood, or thought I did, from earlier parts of this thread that it
should be possible to do what I want, i.e. declare a public enum within
the class whose methods are controlled by the enum values. I've checked
various sources on the interwebs including the Oracle tutorial, but
didn't find anything there, so - what have I missed or misunderstood?
--
Martin | martin at
Gregorie | gregorie dot org
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2018-10-27 19:38 -0400 |
| Message-ID | <pr2sui$me8$1@gioia.aioe.org> |
| In reply to | #38667 |
On 10/27/2018 6:36 PM, Martin Gregorie wrote:
> On Fri, 26 Oct 2018 20:58:44 -0400, Arne Vajhøj wrote:
>> On 10/26/2018 3:33 PM, Martin Gregorie wrote:
>>> which is why I thought it
>>> could not be declared inside a class definition.
>>
>> You can put a class declaration inside a class.
>
> Yes indeed, but as I found out it seems not so simple to access it from
> outside. The following shows how I wanted to declare and use a enum, i.e.
> as a direct a replacement for the set of public static final ints).
> Here's an SSCCE that shows the problem.
>
> public class EnumWrapper
> {
> public enum MyEnum { ONE, TOO, TREE };
> public static void printVal(MyEnum v)
> {
> System.out.println("printval(" + v + ")");
> }
> }
>
> This works as expected with the enum used inside its declaring class:
> BUT, I also want to use it as a parameter when calling a methods in the
> class where the enum is declared, IOW exactly how I'd use a public static
> final int declared in the class:
>
> public class TestRun
> {
> public static void main(String args[])
> {
> EnumWrapper ew = new EnumWrapper();
>
> ew.printval(MyEnum.ONE);
> }
> }
>
> ... and this won't compile:
> and, if I replace 'MyEnum' with "EnumWrapper", the name of the class,
> it still fails to compile:
Normal name rules aka same as for nested classes.
public class TestRun
{
public static void main(String args[])
{
EnumWrapper ew = new EnumWrapper();
ew.printVal(EnumWrapper.MyEnum.ONE);
}
}
should work.
import EnumWrapper.MyEnum;
public class TestRun2
{
public static void main(String args[])
{
EnumWrapper ew = new EnumWrapper();
ew.printVal(MyEnum.ONE);
}
}
should also work.
The enums full name is EnumWrapper.MyEnum so either
full name or an import to use short name.
(in real life there would also be a package, but ...)
Arne
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@mydomain.invalid> |
|---|---|
| Date | 2018-10-28 10:39 +0000 |
| Message-ID | <pr43lo$3rb$1@news.albasani.net> |
| In reply to | #38668 |
On Sat, 27 Oct 2018 19:38:56 -0400, Arne Vajhøj wrote:
> public class TestRun {
> public static void main(String args[])
> {
> EnumWrapper ew = new EnumWrapper();
> ew.printVal(EnumWrapper.MyEnum.ONE);
> }
> }
>
> should work.
>
No, just a compilation failure:
$ javac TestRun.java
TestRun.java:7: error: cannot find symbol
ew.printval(EnumWrapper.MyEnum.ONE);
^
symbol: method printval(MyEnum)
location: variable ew of type EnumWrapper
1 error
The answer in both cases turns out to be to put the sources in a
directory called 'enum_test' and add "package enum_test;" to the sources.
This allowed TestRun to compile and run while the less verbose and
slightly modified TestRun2, with a second call to printVal(), now
compiles and runs with an additional import statement:
package enum_test;
import enum_test.EnumWrapper.*;
public class TestRun2
{
public static void main(String args[])
{
EnumWrapper ew = new EnumWrapper();
ew.printVal(MyEnum.ONE);
ew.printVal(MyEnum.TREE);
}
}
I can live with the additional import statement since it lets me put the
enum where I want it.
Thanks for your help.
--
Martin | martin at
Gregorie | gregorie dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2018-10-28 07:54 -0400 |
| Message-ID | <pr4829$15b$1@dont-email.me> |
| In reply to | #38669 |
On 10/28/2018 6:39 AM, Martin Gregorie wrote:
> [...]
> No, just a compilation failure:
>
> $ javac TestRun.java
> TestRun.java:7: error: cannot find symbol
> ew.printval(EnumWrapper.MyEnum.ONE);
> ^
> symbol: method printval(MyEnum)
> location: variable ew of type EnumWrapper
> 1 error
Try `printVal', with a capital `V'.
--
esosman@comcast-dot-net.invalid
Eight hundred fifteen days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2018-10-26 06:26 -0700 |
| Message-ID | <fef929a1-e6f6-450a-8f39-5d05fe1bcab7@googlegroups.com> |
| In reply to | #38653 |
On Thursday, October 25, 2018 at 5:49:37 PM UTC-4, Eric Sosman wrote:
>
> Also, be careful to distinguish between "there are exactly two
> possibilities" and "I have thought of only two possibilities." It
> is perhaps instructive that the example given would not work for the
> printer that sits on my desk at this moment, which has *five* modes
> for duplexing:
>
> One-sided
>
> Two-sided (automatic, flip on long axis)
>
> Two-sided (automatic, flip on short axis)
>
> Two-sided (manual, flip on long axis)
>
> Two-sided (manual, flip on short axis)
>
> (In the "automatic" modes the printer marks one side but doesn't
> spit the page out, then sucks it back in and does the second side.
> In the "manual" modes it prints and ejects all the back sides, then
> you re-insert the stack in the paper supply and it prints the formerly-
> blank fronts. "Automatic" is more convenient, "Manual" can be faster
> for long documents.)
>
> Duplex-or-not is, as suggested, a Yes/No question -- but if the
> answer is Yes the answer is incomplete, lacking essential detail.
> A good API offers (relatively) straightforward ways to supply all
> the necessary information.
Well you're just full of booleans, they could be overloads.
setDuplex(boolean isDuplex)
setDuplex(boolean isDuplex, boolean flipShortSide)
setDuplex(boolean isDuplex, boolean flipShortSide, boolean auto)
Though a separate method for the not-so-obvious-boolean would be more readable, setFlipOnShortSide(boolean), with flip on long side being the default either way.
It is probably common that boolean options are linked ie calling setFlipOnShortSide() does nothing unless you call setDuplex(true).
I actually can't think of many good examples of true independent boolean parameter examples. It seems more often boolean is used in the return value.
Then we have old school parameter, java.awt.font.TextAttribute is full of static final numeric values, and new school parameter ie javax.print.attribute.standard.Sides. While the documentation for EnumSyntax does say an enum is just an integer, it does auto-validate at compile time, and you don't have to maintain a condition in every method:
if (passInValue < 1 or passInValue > 5) { throw new InvalidParameterException("parameter must be in range of 1 to 5"); }
or deal with stack trace errors.
Most parameters could actually be boolean but is it more or less readable? Is it more or less work?
public class Person{
private int gender = 0;
public void setIsMale(boolean val) {
gender = val == true ? 0 : 1;
}
public void setIsFemale(boolean val) {
gender = val == true ? 1 : 0;
}
public void setIsBiGender(boolean val) {
gender = val == true ? 2 : gender;
}
}
Now if the parameters are self documenting and it is both possible to be both or neither you could use one method
public void setGender(boolean isMale, boolean isFemale)
Some APIs like to name everything arg1 with no javadoc...
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.java.programmer
csiph-web