Is creating anonymous objects bad practice?

P

Peter D.

I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");

The class will do it's business and go away. Or:

new Monitor(someStuff);

Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

What are the drawbacks to using such techniques? I don't see much code
with random new's everywhere so I am wondering if some of the code I
am writing is cruddy... :)

Thanks.
 
O

Owen Jacobson

I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");

The class will do it's business and go away. Or:

new Monitor(someStuff);

Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

What are the drawbacks to using such techniques? I don't see much code
with random new's everywhere so I am wondering if some of the code I
am writing is cruddy... :)

Thanks.

In general, constructors should never have side-effects. Because
constructors run at a time when an object's state is "sensitive" and
may even be incomplete[0], it's far too easy to leave hazards that
will turn into bugs in the future. Side effects should occur through
method calls, which don't normally run when an object is only
partially initialized.

Without side effects, a "naked" new statement with no assignment is a
no-op and could just as well not exist without altering the program.

-o

[0] In the case of your Monitor example, consider what happens if
someone extends Monitor. Your constructor apparently starts a thread,
which begins operating on the newly-constructed object, before the
subclass' constructor is guaranteed to have completed.
 
A

Andreas Leitgeb

Peter D. said:
new LogThis("Log this string");

I'd prefer a static method for this use:
Logger.log("Log this string");
What are the drawbacks to using such techniques?

The drawback would be: useless object creation. Normally,
creating objects makes sense for all the stuff one can do
with an object once it's there. In your case you have the
cost of creation, but seemingly no gain at all from it.
 
A

awec

Peter said:
I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");

The class will do it's business and go away. Or:

new Monitor(someStuff);

Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

What are the drawbacks to using such techniques? I don't see much code
with random new's everywhere so I am wondering if some of the code I
am writing is cruddy... :)

Thanks.
It's how I was taught to do actionlisteners, so I am not sure if there
are any problems with it. Therefore, I'm also interested in the answer
to this.

Cheers
 
G

GArlington

I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");
It really depends...
If you want to log maybe program completion (at the end of the
program) it is OK and I do not think that anybody will disagree...
If you intend to log error/warning(/other) messages during the
application run - why would you want to re-create the object EVERY
time you need to use it?
The class will do it's business and go away. Or:

new Monitor(someStuff);
From the name I guess it will be a separate thread doing the
monitoring, in which case there is NO difference, if you code it
correctly the thread will stop when and only when it needs to stop and
then it will be reclaimed and will remain active otherwise...
Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

What are the drawbacks to using such techniques? I don't see much code
with random new's everywhere so I am wondering if some of the code I
am writing is cruddy... :)

Thanks.

I would say that the result var will be there most of the time just to
check the construction status (success or failure), if you do not need
to know, or you are sure of the result there is no need to keep it...
 
E

Eric Sosman

Peter said:
I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");

The class will do it's business and go away. Or:

new Monitor(someStuff);

Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

What are the drawbacks to using such techniques? I don't see much code
with random new's everywhere so I am wondering if some of the code I
am writing is cruddy... :)

There's a general feeling that a class should not do too
much in its constructor. "Too much" is something of a flexible
concept, but the idea is that constructors ought to be about
initializing objects and not about putting them through their
paces. This makes subclassing a lot easier to deal with (a
superclass constructor that does "too much" with its new object
might get into trouble by doing it with a subclass object whose
own constructor hasn't run yet).

The "not too much" point of view suggests that your LogThis
example might be somewhat out of line -- not "bad practice,"
exactly, but eyebrow-raising.

Your Monitor example is more puzzling, because I'm having
trouble understanding what you mean by "go off and monitor
something," or how the Monitor would inform the rest of the
program about the state of whatever was being monitored. I'd
need a better grasp of what a Monitor does before I could say
whether I thought your way of launching one made sense.
 
A

Andreas Leitgeb

It's how I was taught to do actionlisteners, ...

No, that's a different thing. You usually pass actionlisteners
to some registering method, so you don't really throw away the
object the way Peter asked about.
 
P

Peter D.

Ok this is good information thanks to everyone. I understand that
putting too much code in the constructor of a class is not always a
good idea because when subclassing it might cause problems. Also
sometimes a new class is not always required to do some of the work as
some people mention with the LogThis example. Here is another example
that might or might not make sense:

Lets say my monitor class is monitoring a UDP port for incoming UDP
packets and this class needs to take the data from the packet and pass
it to another class called Action. Is it wrong to:

for( String wMyString : wStringList )
new Action(wMyString);
}

I'm already starting to see that this might be a bad idea... but what
if I know the action class doesn't really need to do anything other
than something simple?
 
E

Eric Sosman

awec said:
Peter said:
I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. [...]

It's how I was taught to do actionlisteners, so I am not sure if there
are any problems with it. Therefore, I'm also interested in the answer
to this.

Peter D. asks about creating an object whose constructor
does everything the object will ever do and then throwing the
new object away. Creating a listener (or other object) and
passing it as an argument to addActionListener (or whatever)
does not "assign to a variable," exactly, but is a far cry from
just throwing the object away. In a sense, the method call
"assigns" the new object's reference to the method's formal
parameter, and addActionListener will presumably store that
reference somewhere for future use.
 
A

Andreas Leitgeb

Peter D. said:
for( String wMyString : wStringList )
new Action(wMyString); Action.do(wMyString);
}

Anyway, a static method can do that simple stuff with
less overhead and less other caveats, and may furthermore
even be less to type :)
 
R

RedGrittyBrick

Peter said:
I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable.

I often do that with Swing components, for example:
panel.add(new JButton(someAction));

I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

I always feel it is wrong to create an object or invoke a method merely
for it's side effects.

new LogThis("Log this string");

I'd have one or more static methods and use it thus:
LogThis.log("Log this string");
or
LogThis.error("something bad happened, exiting");

The class will do it's business and go away. Or:

new Monitor(someStuff);

Which will then go off and monitor something during the runtime of the
application. What if I don't need to access the reference to this
object?

I'd organise the monitoring in a separate method
new Monitor(someStuff).start(otherStuff);

Compare with a typical use of SwingWorker.
new SwingWorker<Void, Void>() {
@Override public Void doInBackGround() ... {
...
}
}.execute();
___^^^^^^^^^^

What are the drawbacks to using such techniques?

Others have pointed out the problems of doing the wrong things in
constructors. See Joshua Bloch's book "Effective Java".

I don't think there are any major drawbacks to anonymous objects. If you
subsequently discover you need a reference to them, it isn't usually
hard to change the code to provide one.

I don't see much code with random new's everywhere

I do (except they are not really random).

so I am wondering if some of the code I am writing is cruddy... :)

IMO only because of the misuse of constructors, not because the objects
are anonymous (not explicitly assigned to variables).
 
R

Roedy Green

new LogThis("Log this string");

It is naughty, but not for the reason you think.

Constructors should construct, not do interesting work. So I would
write that as:u

new LogThis.log("Log this string");

or even more simply:

Log.log("Log this string");

If you don't need to use the object again later, it is just confusing
to save a reference to it you never use.
--
Roedy Green Canadian Mind Products
http://mindprod.com
"Humanity is conducting an unintended, uncontrolled, globally pervasive experiment
whose ultimate consequences could be second only to global nuclear war."
~ Environment Canada (The Canadian equivalent of the EPA on global warming)
 
E

Eric Sosman

Peter said:
Lets say my monitor class is monitoring a UDP port for incoming UDP
packets and this class needs to take the data from the packet and pass
it to another class called Action. Is it wrong to:

for( String wMyString : wStringList )
new Action(wMyString);
}

I'm already starting to see that this might be a bad idea... but what
if I know the action class doesn't really need to do anything other
than something simple?

If Action is all that simple and if you rely on "knowing"
what it does, why make a separate class for it? The very fact
that you've separated the actions of Action into their own
class suggests that you *intend* not to "know" much about it.
 
T

Tom Anderson

Ok this is good information thanks to everyone. I understand that
putting too much code in the constructor of a class is not always a
good idea because when subclassing it might cause problems. Also
sometimes a new class is not always required to do some of the work as
some people mention with the LogThis example. Here is another example
that might or might not make sense:

Lets say my monitor class is monitoring a UDP port for incoming UDP
packets and this class needs to take the data from the packet and pass
it to another class called Action. Is it wrong to:

for( String wMyString : wStringList )
new Action(wMyString);
}

I'm already starting to see that this might be a bad idea... but what if
I know the action class doesn't really need to do anything other than
something simple?

Put it in a static method:

for (String wMyString: wStringList)
Action.run(wMyString);
}

If you insist on creating an object, separate out construction and
execution of the action:

for (String wMyString: wStringList)
new Action(wMyString).run();
}

Using constructors as you describe isn't wrong, but it's poor style.
You're using a facility of the language for a purpose other than that for
which it was intended, which makes your code harder to read for others,
and perhaps yourself. It's like using exceptions for flow control.

tom
 
P

Peter D.

Put it in a static method:

for (String wMyString: wStringList)
        Action.run(wMyString);

}

If you insist on creating an object, separate out construction and
execution of the action:

for (String wMyString: wStringList)
        new Action(wMyString).run();

}

Using constructors as you describe isn't wrong, but it's poor style.
You're using a facility of the language for a purpose other than that for
which it was intended, which makes your code harder to read for others,
and perhaps yourself. It's like using exceptions for flow control.

tom

Thanks to all. I think the drawbacks to this approach are much more
clear.
 
A

awec

Andreas said:
No, that's a different thing. You usually pass actionlisteners
to some registering method, so you don't really throw away the
object the way Peter asked about.
Ah right. I see.

Thanks!
 
A

Arved Sandstrom

Peter D. said:
I've been trying to look this up but I can't really come to a
conclusion. Is it bad practice to create an object like so:

new MyObject(param1, param2);

Without assigning it to a variable. I know this is accepted to some
degree but lets say I just wanted a class to do some work on the side
without caring about the result of the work it has done for example:

new LogThis("Log this string");
[ SNIP ]

To put it very succinctly, people expect constructors to return an
initialized object. And that's all a constructor should do. It will confuse
other people reading your code if you start non-initialization in a
constructor. In your above example a maintenance programmer would figure it
out, but it's not always that obvious.

If you want to keep things succinct, try

new LogThis().log("Log this string");

AHS
 
A

Andreas Leitgeb

Arved Sandstrom said:
new LogThis().log("Log this string");

Unless the log-method really really needs an instance
of its class, this is almost as bad as the constructor
thingie. "Almost" (and not "entirely"), because at least
we do not use incomplete objects that way.

Just make log static and do Logthis.log(...);
 
A

Arne Vajhøj

Andreas said:
Unless the log-method really really needs an instance
of its class, this is almost as bad as the constructor
thingie. "Almost" (and not "entirely"), because at least
we do not use incomplete objects that way.

Just make log static and do Logthis.log(...);

It is seen quote frequently.

And if you only need to do a single call here
but do need to make multiple calls elsewhere, then
I prefer this over having both a non-static and
a static method.

I tend to prefer:

(new C()).m();

over:

new C().m();

but that is a minor point.

Arne
 
E

Eric Sosman

Andreas said:
Unless the log-method really really needs an instance
of its class, this is almost as bad as the constructor
thingie. "Almost" (and not "entirely"), because at least
we do not use incomplete objects that way.

Just make log static and do Logthis.log(...);

Well, there's the possibility that Log might have more
than one constructor:

new LogThis().log("Log this string");
new LogThis("foo.log").log("Log this string");
new LogThis("foo.log", LogThis.PRIORITY_MEDIUM)
.log("Log this string");

Even so, though, it looks pretty silly to (presumably)
create/open, write to, and flush/close a log in the
LogThis constructor. Makes retaining a LogThis instance
sort of useless, no?
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top