24

I've seen objects created in Java code without storing a reference to the object. For example, in an eclipse plugin I've seen a SWT Shell created like so:

new Shell(); 

This new Shell object is not stored in a variable, but will remain referenced until the window is disposed which [I believe?] happens by default when the window is closed.

Is it bad practice to create objects like this without storing a reference to them? Or was the library poorly designed? What if I don't have need of a reference, but only want the "side effects" of the object? Should I store a reference anyways?

UPDATE:

Admitedly, my above example is poor. While I have seen UI elements created like this, creating a SWT Shell like this would probably be pointless because you need to call the open method on the Shell instance. There are better examples provided by aix such as the following from the Java concurrency tutorial:

(new HelloThread()).start(); 

This practice is seen in many contexts, so the questions remains. Is it good practice?

8
  • 3
    What would be the point of storing the reference? Commented Jan 12, 2012 at 20:22
  • (It probably would be better, from a conceptual point of view, to have a static method such as Shell.createTopLevelShell() or whatever, vs using a constructor in this case. But functionally there's little difference.) Commented Jan 12, 2012 at 20:25
  • Is this question about the practice of creating objects without referring to them, creating classes that require this practice, or is it specifically about the way SWT uses this sort of pattern? Commented Jan 12, 2012 at 20:34
  • 1
    SWT objects must be dispose()d: Rule 1: If you created it, you dispose it. eclipse.org/articles/swt-design-2/swt-design-2.html Commented Jan 12, 2012 at 20:40
  • 2
    I would use a variable to hold a reference for debugging purposes. If you have a break point in this method then you can get the debugger to query the object via the local variable. Without the reference I am sure it is possible but probably a lot harder. Commented Jan 12, 2012 at 22:35

6 Answers 6

15

There's an element of personal preference to this, but I think that not storing the reference is not necessarily a bad practice.

Consider the following hypothetical example:

new SingleFileProcessor().process(file); 

If a new processor object needs to be created for every file, and is not needed after the process() call, there's no point in storing a reference to it.

Here is another example, taken from the Java concurrency tutorial:

(new HelloThread()).start(); 

I've seen lots of other examples when the reference is not stored, and that read perfectly fine to my eye, such as:

String str = new StringBuilder().append(x).append(y).append(z).toString(); 

(The StringBuilder object is not kept.)

There are similar patterns involving common.lang's HashCodeBuilder et al.

2
  • It's up to the factory whether to use a singleton or not. Caller of the factory shouldn't think about it too much. Commented Jan 12, 2012 at 20:33
  • In your example the FileProcessor instance is (presumably) not needed once the statement is complete, whereas in the OP's example the Shell instance is (under the covers) referenced by another object, and that reference (and therefore the Shell object) persists beyond the duration of the statement. Commented Jan 12, 2012 at 20:33
9

If you don't need a reference to the created object, then don't hold onto the reference. It's as simple as that.

1
  • Violating this simple idea causes Memory Leaks. Commented Aug 28, 2022 at 15:18
5

In general, it's good practice to release references as quickly as they can reasonably be released. I see no difference between:

HelloThread thread = new HelloThread(); thread.start(); // where thread is never used for the rest of the method 

and

(new HelloThread()).start(); 

As far as the code is concerned, you're just avoiding the use of a variable name, which could be a positive thing. The JIT compiler is generally smart enough to recognize it can garbage collect the thread after its last use, so there's probably no difference from a performance standpoint.

The only real issue to avoid is the Code in the Constructor Anti-Pattern, but it doesn't sound like that's what you're asking about.

3

This could be bad if you're using SWT, because there you have to clean up after yourself (calling the dispose() method). But for other classes (non SWT) it's ok.

Here's an article about Managing Operating System Resources

9
  • Circular references do not prevent objects from being garbage collected in Java. Any modern Java VM determines whether objects are GCable based on whether they are reachable, and does not use reference counting. Commented Jan 12, 2012 at 20:26
  • 2
    Indeed it doesn't use reference counting. But SWT is a special case where we do need to call dispose(), though there is no need to call any retain() first. Commented Jan 12, 2012 at 20:30
  • I meant to refer only to the non-SWT case. Commented Jan 12, 2012 at 20:33
  • Here's an article about Managing Operating System Resources eclipse.org/articles/swt-design-2/swt-design-2.html Commented Jan 12, 2012 at 20:34
  • 2
    In that case edit your answer to remove the statement about “impossible to GC” as it is misleading. Commented Jan 12, 2012 at 20:34
0

First of all, you're going to annoy people who learned C or C++ before Java. I'll leave that as an exercise for the reader to decide if that's a pro or a con.

While there are certainly situations in which objects are designed to be very short-lived, most of the time if something is complex enough to create an object for, it's complex enough to have good reasons to keep a reference, so not keeping it should at the very least be a warning to double check if you have missed something.

For example, in a tutorial no one cares about keeping a thread reference, but in real life, if something takes long enough that you want to spawn a thread, it usually takes long enough that you want to be able to cancel the thread. Or if shorter-lived, you usually are spawning a bunch of threads you will want to join before continuing. Or you want to make sure your thread creation actually succeeded. Or you want to make sure the thread finishes cleanly before exiting. You get the picture.

2
  • 2
    Is worrying about annoying programers from other languages really the first concern? Commented Jan 13, 2012 at 16:40
  • It makes it a readability/familiarity/style issue depending on the composition of your team, because it's a style a lot of people carry over. Even people who have never programmed in C++ often adopt styles from their mentors who did. Commented Jan 13, 2012 at 17:26
0

One good reason to create a reference is so you can give it a good, useful name to aid in documentation, especially of the class name is poor or overly general. e.g. (somewhat contrived)

HelloThread helloBasedUponPrivilige = new HelloThread(userLoginInfo); helloBasedUponPrivilige.start(); 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.