Initializing Variables

T

Tom Anderson

There are exceptions to this rule (pun intended)

Foo foo = null;

try {
foo = new Foo();
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

In this case you have to initialize the variable foo.

No, because you should just write it like this:

Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in a
try-catch or whatever.

tom
 
T

Tom Anderson

Not as I read it, but maybe it is.

Regardless, JIT requires multiple executions (by default 10,000 IIRC)
before it decides to optimize something. By definition, initialization
code is run once.

Um, once per instance. If it's an instance initializer. Which is what i
thought we were talking about here. That could easily be run 10 000 times
in a single program.
Regardless, as you pointed out and I reiterated, the performance impact is
not enough to trump issues of readability or self-documentation. Nor is it
required to initialize member variables to their default values.

I admit it's possible that I read this wrong, but I think not.

I don't see how a statement like that is even meaningful when applied to a
JVM. You can require that a JVM behaves *as if* it does or doesn't do
something, defined in terms of some model of what the JVM is doing, but as
long as it does, it can do it however it likes. I don't see how rules to
the contrary would be useful or even possible to judge compliance to.

tom
 
E

Eric Sosman

Um, once per instance. If it's an instance initializer. Which is what i
thought we were talking about here. That could easily be run 10 000
times in a single program.


I don't see how a statement like that is even meaningful when applied to
a JVM. You can require that a JVM behaves *as if* it does or doesn't do
something, defined in terms of some model of what the JVM is doing, but
as long as it does, it can do it however it likes. I don't see how rules
to the contrary would be useful or even possible to judge compliance to.

A suppressed initialization can be observed:

class Super {
Super() {
evilCode();
}

void evilCode() { }
}

class Sub extends Super {
int value = 0; // suppressible?

Sub() {
System.out.println("value = " + value);
}

void evilCode() {
value = 42;
}

public void main(String[] unused) {
new Sub();
}
}

Yes, this is evil code that merits severe chastisement of its author,
but despite its sins it is perfectly legal Java -- and the required
output is "value = 0". If the initialization were suppressed, the
output would be "value = 42" -- and that would (was?) wrong.
 
T

Tom Anderson

No, because you should just write it like this:

Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in a
try-catch or whatever.

If the handling for FooExceptions from the constructor and the processing
is the same:

try {
Foo foo = new Foo();
try {
foo.doProcessing();
}
finally {
foo.cleanup();
}
}
catch (FooException ex) [
doSomething(ex);
}

tom
 
L

Lew

Tom said:
Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in
a try-catch or whatever.

If the handling for FooExceptions from the constructor and the
processing is the same:

try {
Foo foo = new Foo();
try {
foo.doProcessing();
}
finally {
foo.cleanup();
}
}
catch (FooException ex) [
doSomething(ex);
}

Beautiful idioms.

A third, uglier but formally correct idiom is:

final Foo resource;
try
{
resource = new Foo();
}
catch ( FooException ex )
{
log( ex );
return;
}
assert resource != null;
try
{
resource.process();
}
catch ( FooException ex )
{
log( ex );
}
finally
{
resource.cleanup();
}
 
A

Arne Vajhøj

Not as I read it, but maybe it is.

Regardless, JIT requires multiple executions (by default 10,000 IIRC)
before it decides to optimize something. By definition, initialization
code is run once.

Unless it is static then it will be run once per instantiation. That
could be many times.

Arne
 
A

Arne Vajhøj

There are exceptions to this rule (pun intended)

Foo foo = null;

try {
foo = new Foo();
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

In this case you have to initialize the variable foo.

True.

But you should test for null before calling cleanup to handle
the case where the Foo constructor throws FooException.

Arne
 
A

Arne Vajhøj

No, because you should just write it like this:

Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in a
try-catch or whatever.

But in that case the improvement is so so.

Arne
 
R

RedGrittyBrick

Tom said:
Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in
a try-catch or whatever.

If the handling for FooExceptions from the constructor and the
processing is the same:

try {
Foo foo = new Foo();
try {
foo.doProcessing();
}
finally {
foo.cleanup();
}
}
catch (FooException ex) [
doSomething(ex);
}

Beautiful idioms.

A third, uglier but formally correct idiom is:

final Foo resource;
try
{
resource = new Foo();
}
catch ( FooException ex )
{
log( ex );
return;
}
assert resource != null;
try
{
resource.process();
}
catch ( FooException ex )
{
log( ex );
}
finally
{
resource.cleanup();
}

I'm always a little uncomfortable when the exception handling overwhelms
and obscures the business logic:

new Foo().process().cleanup(); // <stimpy>Sigh!</stimpy>

The point of the exception handling mechanism is to separate error
handling code from business logic code. Sometimes it is hard to achieve
this.
 
P

Pitch

No, because you should just write it like this:

Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in a
try-catch or whatever.

tom


If new Foo() throws an exception it's not a problem. If you see this
block as an atomic function "doSomethingFoo()" the caller has to handle
exceptions but the callee has to clean up resources it has allocated.

On the other hand if you DON'T see this as an atomic function - I'd say
it's bad design. :)
 
P

Pitch

But in that case the improvement is so so.

Improvement is in that it forces you to decouple your code into smaller
methods, which is a huge thing to me.


Anyway, it's an old subject, we've all already disagreed on that a year
ago. :)
 
L

Lew

RedGrittyBrick said:
I'm always a little uncomfortable when the exception handling overwhelms
and obscures the business logic:

new Foo().process().cleanup(); // <stimpy>Sigh!</stimpy>

Is your sigh because the 'cleanup()' call might never happen this way?

This simplified code represents the problem the other idioms solve.
The point of the exception handling mechanism is to separate error
handling code from business logic code. Sometimes it is hard to achieve
this.

The point of the 'finally' block is to ensure code runs even when earlier code
completes abruptly.
 
M

Mike Amling

Patricia said:
I follow the extreme opposite view. I initialize a local variable at the
point of declaration if doing so makes logical sense or I know that I
know something the compiler does not know. Generally, that involves the
compiler assuming a fall-through from a call to System.exit.

I started following all calls to System.exit and to my own
non-returning functions with

throw DONT;

to notify the compiler. That allows it to do assignment checks and to
find dead code. (DONT is a statically declared RuntimeException instance
that is never actually thrown.)

--Mike Amling
 
R

Roedy Green

Basically, I initialize pretty much every variable as I declare it, just to
be sure it has some kind of value right away. That initial value is
typically a zero for a number or a null for an object. Some recent
criticism questioned this practice so I thought I'd review some of the
material that helped get me in that habit in the first place.

If that interim value is meaningless, you prevent the compiler from
detecting missing "real" initialisations.
--
Roedy Green Canadian Mind Products
http://mindprod.com

Beauty is our business.
~ Edsger Wybe Dijkstra (born: 1930-05-11 died: 2002-08-06 at age: 72)

Referring to computer science.
 
Joined
Jun 14, 2010
Messages
10
Reaction score
0
i initialize all values if they are to be checked.

e.g., if i have to rely on a value being null, i always do

Object flag = null;

otherwise, i use the defaults
 

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,777
Messages
2,569,604
Members
45,218
Latest member
JolieDenha

Latest Threads

Top