Signs of stupid Java code

D

Darryl L. Pierce

Chris said:
That one, I definitely would have rejected out-of-hand, actually. It
strikes me as very ugly. In the end, I don't look at casting null as
something to avoid, as it seems you do.

Ah! But, I never said it was ugly. I said that casting null to some other
type in order to invoke an overloaded method is indicative (to me, at
least) that there's a problem in the design of the class; i.e., if there's
a case where invoking the method without what was considered a required
parameter means that perhaps either an overloaded version of the method
without that argument is in order, or else the code invoking the method is
doing something incorrectly.

<snip>
 
X

xarax

Darryl L. Pierce said:
There's too little information to make a determination here. Do both
versions of foo do the same thing? If so, and if it's acceptable to have
neither a String more a Map, then I again say that a 2-arg overloaded
version is required, or else a foo that specifically is for a
foo-without-a-string (since it's no longer overloading that version) or the
same for the map version for the same reason.

A similar, but subtly different example:

protected void fubar(Gronk gronk)
{
// whatever
}

protected void fubar(Snonk snonk)
{
// whatever
}


If you make a no-arg version of "fubar()", then which
of the overloaded methods is implied with a null arg?

In this case, you need an explicit cast to tell the
compiler which overloaded fubar method you want to call.
 
D

Darryl L. Pierce

xarax said:
A similar, but subtly different example:

protected void fubar(Gronk gronk)
{
// whatever
}

protected void fubar(Snonk snonk)
{
// whatever
}


If you make a no-arg version of "fubar()", then which
of the overloaded methods is implied with a null arg?

You're repeating the same example that has been presented a few times now
without answering the question of the requirement. As I said in another
message, if you're invoking a method with an explicit null, then there must
be a requirement for a no-arg version of fubar(). Either that, or the
invoking method is coded incorrectly or breaking with the public contract
of the class.
In this case, you need an explicit cast to tell the
compiler which overloaded fubar method you want to call.

I understand that. Re-read the other messages I've posted on this subject to
see what I'm talking about. I'm talking about requirements. I understand
that casting null to a type is a way of telling the compiler which version
you want to invoke. What I'm saying is that if you're doing that, then
there's probably a problem with your design: either the client class is
misusing the server class, or the server class should have a no-arg version
of the method in question, or the server class should have another method
to do what you're trying to do. Perhaps the fubar() class should have
another method that both services the fubar() methods that you described
*and* which lets you do the functionality that you require with your no-arg
invokation?
 
A

A. Craig West

Darryl L. Pierce said:
xarax wrote:
You're repeating the same example that has been presented a few times now
without answering the question of the requirement. As I said in another
message, if you're invoking a method with an explicit null, then there must
be a requirement for a no-arg version of fubar(). Either that, or the
invoking method is coded incorrectly or breaking with the public contract
of the class.

I think the point is that it requires TWO no-arg versions of fubar, one where
the intent is to do whatever is appropriate for Gronk's, and one for Snonk's.
This is not likely to be the type of thing that comes up often, but it does
come up. It would always be possible to just give the method a more specific
name, but there are those who feel that the type of the argument is
sufficient, and adding a modifier to the name is redundant.
 
C

Chris Uppal

Doug said:
Besides, I wouldn't synchronize on "new Object()" anyway; why create
an object each time through?

One reason would be to avoid "inflating" the lock of the long lived object and
thus leading to slow-path synchronisation.

Still a spooky technique, though -- calling for a small essay in the comments,
not just a one-liner.

-- chris
 
C

Chris Uppal

Darryl said:
You're repeating the same example that has been presented a few times now
without answering the question of the requirement. As I said in another
message, if you're invoking a method with an explicit null, then there
must be a requirement for a no-arg version of fubar().

Incidentally, how would you implement the no-args version ? Looking back I
think that all the times I've used an explicit cast of null, it's been inside a
method that is best implemented (internally) as forwarding null to some
other existing method (or ctor).

-- chris
 
C

Chris Smith

Ah! But, I never said it was ugly. I said that casting null to some other
type in order to invoke an overloaded method is indicative (to me, at
least) that there's a problem in the design of the class; i.e., if there's
a case where invoking the method without what was considered a required
parameter means that perhaps either an overloaded version of the method
without that argument is in order, or else the code invoking the method is
doing something incorrectly.

Hmm. Just out of curiosity, then, do you oppose *all* methods whose
common usage involves passing literally null parameters, or just those
that are overloaded such as to require casting the null parameter?

The point of my example was that I agree that having to cast a null to
some class is dumb when the call means the same thing either way, and is
only necessary to appease the compiler. However, there are also cases
when it matters quite much which of the overloads is chosen, because a
few different tasks which can receive null parameters are similar enough
to justify overloading in the abstraction, but radically different in
implementation, so that it *does* matter what the type of the null
reference is. But you won't agree if you think that passing a literal
null as a parameter is always inherently wrong, regardless of the
overloading situation.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Bent C Dalager

I understand that. Re-read the other messages I've posted on this subject to
see what I'm talking about. I'm talking about requirements. I understand
that casting null to a type is a way of telling the compiler which version
you want to invoke. What I'm saying is that if you're doing that, then
there's probably a problem with your design: either the client class is
misusing the server class, or the server class should have a no-arg version
of the method in question, or the server class should have another method
to do what you're trying to do. Perhaps the fubar() class should have
another method that both services the fubar() methods that you described
*and* which lets you do the functionality that you require with your no-arg
invokation?

How about use for implementation of the overloaded methods? E.g.,

public class Dumper
{
public static void dump(String string)
{
System.out.println("dump at " + new Date() + ": " + string);
}

public static void dump(char[] string)
{
dump(new String(string));
}

public static void dump()
{
dump((String) null);
}
}

Cheers
Bent D
 
D

Darryl L. Pierce

Chris said:
Hmm. Just out of curiosity, then, do you oppose *all* methods whose
common usage involves passing literally null parameters, or just those
that are overloaded such as to require casting the null parameter?

I _question_ any method which takes an explicit null as an argument. Unless
it's a case where the null is an acceptable type (such as, say, the value
for a hash) then I would most likely reject the API as poorly designed. If
there's a need to invoke a method an pass an explicit null, then that's a
sign that the method needs to be overloaded without the argument.
The point of my example was that I agree that having to cast a null to
some class is dumb when the call means the same thing either way, and is
only necessary to appease the compiler. However, there are also cases
when it matters quite much which of the overloads is chosen, because a
few different tasks which can receive null parameters are similar enough
to justify overloading in the abstraction, but radically different in
implementation, so that it *does* matter what the type of the null
reference is. But you won't agree if you think that passing a literal
null as a parameter is always inherently wrong, regardless of the
overloading situation.

I never said it was always wrong. I said that it indicates a flaw in the
design. That flaw may not exist, but the minute null is being passed to get
around the compiler, to me that signals a problem.
 
D

Darryl L. Pierce

Chris said:
Incidentally, how would you implement the no-args version ?

Of *what*? The above is very hypothetical and not well defined. What does
fubar do? Is there some common functionality between fubar(Gronk) and
fubar(Snonk) and is that functionality the same as what is desired when
either passed argument is null? And can that common functionality be moved
to a no-arg version that can be invoked instead of passing a cast null
reference?
Looking back
I think that all the times I've used an explicit cast of null, it's been
inside a method that is best implemented (internally) as forwarding null
to some other existing method (or ctor).

In a case where it's hidden inside the implementation it's better than when
it's being done through the public contract of a class. I thought I had
specified that as well. As a matter of fact, I *did* say I was talking
about the public contract of a the class in the message to which you're
replying...
 
D

Darryl L. Pierce

A. Craig West said:
I think the point is that it requires TWO no-arg versions of fubar, one
where the intent is to do whatever is appropriate for Gronk's, and one for
Snonk's.

If there's such a divergence in functionality then the two methods shouldn't
be overloaded versions of the same, eh? You can't have two no-arg versions
and if the logic would require two then there's *another* design flaw:
misused overloading.

If a method has two overloaded forms, then those two overloaded forms must
do the same functionality and only vary in the arguments they take in. If
they vary in functionality then they are most likely poorly named (a misuse
of method overloading) and that is a design flaw. If they have the same
functionality, and it's necessary that you be able to invoke that
functionality without a passed argument, then the design calls for an
explicit no-arg version of the method as well. Any functionality that can
be done *without* the passed arguments should be moved to the no-arg method
and those versions *with* arguments should invoke that method as necessary
during their execution.
This is not likely to be the type of thing that comes up often,
but it does come up. It would always be possible to just give the method a
more specific name, but there are those who feel that the type of the
argument is sufficient, and adding a modifier to the name is redundant.

But, the arguments *aren't* different; the casting of null to a type is to
make a different argument (null) the same *same* and depending on the
implementation to differentiate the argument from a non-null one. If the
method can function without arguments, then there should be a no-arg
version of the method.
 
?

=?ISO-8859-1?Q?Thomas_Gagn=E9?=

Darryl said:
I _question_ any method which takes an explicit null as an argument. Unless
it's a case where the null is an acceptable type (such as, say, the value
for a hash) then I would most likely reject the API as poorly designed. If
there's a need to invoke a method an pass an explicit null, then that's a
sign that the method needs to be overloaded without the argument.
But after overloading doesn't the method with the null argument remain?
The new one created without the argument would implement itself by
calling the one with the argument, no? Are you advocating to get rid of
the null argument completely?
 
S

Sudsy

Darryl said:
I _question_ any method which takes an explicit null as an argument. Unless
it's a case where the null is an acceptable type (such as, say, the value
for a hash) then I would most likely reject the API as poorly designed. If
there's a need to invoke a method an pass an explicit null, then that's a
sign that the method needs to be overloaded without the argument.

This thread started as a request for examples of stupid java code.
Now Darryl is questioning some of my code.
For some database work I was doing a while back I created a wrapper
around a table row. When updating the information in the row (prior
to executing an update) I found it useful to provide both individual
mutator methods (setXXX()) and an "all-at-once" option, i.e.
setFields( String lastName, String firstName, ... )
The idea being that it was easier to accept data from a form which
didn't require entry of ALL attributes. So there could easily be a
case where the above method would be invoked as:
setFields( lastName, null, ... )
Other times as:
setFields( null, firstName, ... )
So how am I supposed to overload the method when I have multiple
arguments of the same type?!

Now back to your regularly scheduled program...
 
X

xarax

Darryl L. Pierce said:
If there's such a divergence in functionality then the two methods shouldn't
be overloaded versions of the same, eh? You can't have two no-arg versions
and if the logic would require two then there's *another* design flaw:
misused overloading.

If a method has two overloaded forms, then those two overloaded forms must
do the same functionality and only vary in the arguments they take in. If
they vary in functionality then they are most likely poorly named (a misuse
of method overloading) and that is a design flaw. If they have the same
functionality, and it's necessary that you be able to invoke that
functionality without a passed argument, then the design calls for an
explicit no-arg version of the method as well. Any functionality that can
be done *without* the passed arguments should be moved to the no-arg method
and those versions *with* arguments should invoke that method as necessary
during their execution.


But, the arguments *aren't* different; the casting of null to a type is to
make a different argument (null) the same *same* and depending on the
implementation to differentiate the argument from a non-null one. If the
method can function without arguments, then there should be a no-arg
version of the method.


Suppose fubar(Gronk gronk) was actually "actionThing(ActionEvent actionEvent)",
and fubar(Snonk snonk) was actually "actionThing(PropertyChangeEvent
propertyChangeEvent)".

You have an "actionThing" that can receive either an ActionEvent
or a PropertyChangeEvent, and both methods have their own special
behavior when the argument is null. This is not a contrived or
stupid design.

Your insistence that whenever you see "snafu((Thing) null)", it *must*
be an API design error, is itself fundamentally flawed.
 
D

Darryl L. Pierce

Sudsy said:
This thread started as a request for examples of stupid java code.
Yep.

Now Darryl is questioning some of my code.

I am? Where did I question your code? I don't see where I've even responded
to you previous...
For some database work I was doing a while back I created a wrapper
around a table row. When updating the information in the row (prior
to executing an update) I found it useful to provide both individual
mutator methods (setXXX()) and an "all-at-once" option, i.e.
setFields( String lastName, String firstName, ... )
The idea being that it was easier to accept data from a form which
didn't require entry of ALL attributes. So there could easily be a
case where the above method would be invoked as:
setFields( lastName, null, ... )
Other times as:
setFields( null, firstName, ... )
So how am I supposed to overload the method when I have multiple
arguments of the same type?!

You're taking my original statements and twisting them around to a single
example. Where did I say my position was a hard-and-fast rule for
development? You might want to spend a moment to see what my position *is*
before looking for exceptions to claim I'm wrong.
 
D

Darryl L. Pierce

Thomas said:
But after overloading doesn't the method with the null argument remain?

Possibly. It depends on how the code is refactored. I think perhaps some of
you are focusing too much on the public contract and not looking at the
implementation. For example:

public class Foo
{
private Object barvalue = null;

public void bar(String s)
{
this.barvalue = s;
procesBarValue();
}

public void bar(Integer i)
{
this.barvalue = i;
processBarValue();
}

public void bar()
{
this.barvalue = null;
processBarValue();
}

// implementation details

private void processBarValue()
{
// here there be dragons
}
}
The new one created without the argument would implement itself by
calling the one with the argument, no?

No, not necessarily. See the above example. Don't confuse public contracts
with implementation details.
Are you advocating to get rid of
the null argument completely?

Where did I say any such thing? I said that if you have to cast null to a
specific type in order to invoke a method that's expecting a specific type,
then that's a signal that there's a potential problem with the design. I'm
reading alot of people who are defending the approach by saying it's legal
and that it's to tell the compiler what you intend, but I'm not looking at
implementation and am instead saying that it's a signal that perhaps a
no-arg (or at least a without-that-specific-arg) version of the method is
called for.
 
D

Darryl L. Pierce

xarax said:
Suppose fubar(Gronk gronk) was actually "actionThing(ActionEvent
actionEvent)", and fubar(Snonk snonk) was actually
"actionThing(PropertyChangeEvent propertyChangeEvent)".

You have an "actionThing" that can receive either an ActionEvent
or a PropertyChangeEvent, and both methods have their own special
behavior when the argument is null. This is not a contrived or
stupid design.

Mate, you can change the names of the methods and the purpose of them till
the cows come home, it doesn't change the basic premise of what I've said.
Sure they can behave differently if a null event is passed in the course of
execution. But, if you are *explicitly* passing it null (rather than that
null being the result of a different operation) then you've surfaced a
potential design flaw.
Your insistence that whenever you see "snafu((Thing) null)", it *must*
be an API design error, is itself fundamentally flawed.

When did I say "it *must* be an API design error" or anything that say it
was definitely so? I've said, repeatedly, that is signals a *potential*
error in the design. I've been very clear on my position and you seem to
be instead arguing a straw man construct that has nothing to do *with*
my position.
 
C

Chris Smith

Darryl said:
I never said it was always wrong. I said that it indicates a flaw in the
design. That flaw may not exist, but the minute null is being passed to get
around the compiler, to me that signals a problem.

We must not be communicating well. To me, the phrases "it is always
wrong" and "it indicates a flaw in the design" are equivalent, except
that the latter says something about why it's always wrong. I'm having
trouble understanding the phrase otherwise.

In any case, I agree that such instances are often candidates for API
changes, and you seem to agree that they occasionally are not. So I
don't know what we're discussing.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
D

Darryl L. Pierce

Chris said:
We must not be communicating well. To me, the phrases "it is always
wrong" and "it indicates a flaw in the design" are equivalent, except
that the latter says something about why it's always wrong. I'm having
trouble understanding the phrase otherwise.

Perhaps it's just that, a problem in communication. To be clear: I have
*not* said that this indicates that there *definitely is* an error in the
design. I've said that it's a *signal* that there is a *potential* error in
the design. Just as a cough indicates someone *might* have a cold, casting
null to a type is a signal that the design needs to be reviewed.
In any case, I agree that such instances are often candidates for API
changes, and you seem to agree that they occasionally are not. So I
don't know what we're discussing.

Neither do I. There seem to be a few elements here who think I've claimed
some law with my position and are debating that straw man instead...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,123
Latest member
Layne6498
Top