How to solve the error "The local variable may not have been instantiated"?

S

Shawn

Hi,

I found an error very annoying. I am hoping someone can give me some
suggestion.


public MyClass getMyClass
{
MyClass myClass = null;

//opens a gui for the user. Normally, the user clicks the button
//and the object myClass gets created. But if the user clicks
Cancel button, then myClass will not be created
if (....) //user clicks the button
{
myClass = new MyClass(..); //myClass object created here
}
else //user clicks the Cancel button
{
System.out.println("User has cancelled the command");
}

return myClass; //NOW, my compiler won't let me go. It says the
local variable myClass may not have been instantiated.
}

instead, the following code works:

public MyClass getMyClass
{
MyClass myClass = null;

if (....) //user clicks the button
{
myClass = new MyClass(..); //myClass object created here
...
return myClass;
}
else //user clicks the Cancel button
{
System.out.println("User has cancelled the command");
return null;
}
}

It ends up with two returns, which I don't like. I don't understand why
I cannot pass with the first code.

Thank you very much.
 
I

Ingo R. Homann

Hi Shawn,
Hi,

I found an error very annoying. I am hoping someone can give me some
suggestion.


public MyClass getMyClass
{
MyClass myClass = null;
^^^^^^^
If you do not forget this assignment, it works perfectly!
if (....) //user clicks the button
{
myClass = new MyClass(..); //myClass object created here
}
else //user clicks the Cancel button
{
System.out.println("User has cancelled the command");
}

return myClass;
}

On the other hand, this...
public MyClass getMyClass
{
MyClass myClass = null;

if (....) //user clicks the button
{
myClass = new MyClass(..); //myClass object created here
...
return myClass;
}
else //user clicks the Cancel button
{
System.out.println("User has cancelled the command");
return null;
}
}

....can be done even simpler:

public MyClass getMyClass
{
if (....) //user clicks the button
{
return new MyClass(..); //myClass object created here
}
else //user clicks the Cancel button
{
System.out.println("User has cancelled the command");
return null;
}
}

And I would prefer this solution!
It ends up with two returns, which I don't like.
Why?

> I don't understand why
I cannot pass with the first code.

Well, it can!

Ciao,
Ingo
 
S

Shawn

Ingo said:
Hi Shawn,

^^^^^^^
If you do not forget this assignment, it works perfectly!



Well, it can!

Thank you for your help. I didn't forget "= null;". My program still
doesn't work. This is what I saw. If you insist, maybe it has to do with
settings of compiler. I know regards to warnings, user can make
selections so that somethings are considered as warnings, some not.
> ...can be done even simpler:
>
> public MyClass getMyClass
> {
> if (....) //user clicks the button
> {
> return new MyClass(..); //myClass object created here
> }
> else //user clicks the Cancel button
> {
> System.out.println("User has cancelled the command");
> return null;
> }
> }

This won't work for me. I simplified my program in the posting. In my
real program, after myClass object was created, the object was used
several times. So it cannot be inside the if block:

return new MyClass(..); //myClass object created here
 
I

Ingo R. Homann

Hi,
Thank you for your help. I didn't forget "= null;". My program still
doesn't work. This is what I saw. If you insist, maybe it has to do with
settings of compiler. I know regards to warnings, user can make
selections so that somethings are considered as warnings, some not.

Yes, I insist, and no, it has nothing to do with compiler-settings. It
has to do with the reduction/simplification of your code you posted
here. What you have posted does work.
This won't work for me. I simplified my program in the posting. In my
real program, after myClass object was created, the object was used
several times. So it cannot be inside the if block:

OK - but I still do not understand why you do not like the two returns.

Ciao,
Ingo
 
P

Patricia Shanahan

Ingo said:
Hi,


Yes, I insist, and no, it has nothing to do with compiler-settings. It
has to do with the reduction/simplification of your code you posted
here. What you have posted does work.


OK - but I still do not understand why you do not like the two returns.

I used to dislike multiple returns, in languages that did not have
try-finally or equivalent.

They were a problem if some additional code needed to be inserted to run
before the function returns, for example for debug.

However, I also have trouble understanding the dislike for multiple
returns in Java.

Patricia
 
?

=?ISO-8859-15?Q?Tobias_Schr=F6er?=

Hi,
Thank you for your help. I didn't forget "= null;". My program still
doesn't work. This is what I saw. If you insist, maybe it has to do with
settings of compiler. I know regards to warnings, user can make
selections so that somethings are considered as warnings, some not.

I think not. If you've assigned at least null to your variable, the
compiler should not warn you. Strange, indeed.
This won't work for me. I simplified my program in the posting. In my
real program, after myClass object was created, the object was used
several times. So it cannot be inside the if block:

return new MyClass(..); //myClass object created here

Maybe try to use something like this:

public MyClass getMyClass() {
//.. some code ..
if (...) {
MyClass myClass = new MyClass(...);
// .. more code, that uses myClass
return myClass;
}

// user cancel
System.out.println("User has cancelled the command");
return null;
}

Looks quite similar to your working solution ;)
Why don't you want two returns?

Tobi
 
P

Patricia Shanahan

Shawn wrote:
....
Thank you for your help. I didn't forget "= null;". My program still
doesn't work. This is what I saw. If you insist, maybe it has to do with
settings of compiler. I know regards to warnings, user can make
selections so that somethings are considered as warnings, some not.

The initialization issue is an error, not a warning. The compiler should
never compile something with a possibly not initialized local variable,
because the results are undefined.

....
This won't work for me. I simplified my program in the posting. In my
real program, after myClass object was created, the object was used
several times. So it cannot be inside the if block:

return new MyClass(..); //myClass object created here

You should not get the "may not have been initialized" for a variable
that has an initial value in its declaration, as in:

MyClass myClass = null;

Make sure you only have one declaration with identifier myClass, so that
there is only one variable with that name.

If you are still having trouble, please post a short self-contained
example that reproduces it.

Patricia
 
J

Jussi Piitulainen

Ingo said:
Yes, I insist, and no, it has nothing to do with
compiler-settings. It has to do with the
reduction/simplification of your code you posted
here. What you have posted does work.

This could be settled if Shawn posted a complete program
that fails. The following compiles and runs just fine.

public class MyClass {
public static void main(String [] args) {
getMyClass(args.length == 0);
}

private static MyClass getMyClass(boolean condition) {
MyClass myClass = null;
if (condition) {
myClass = new MyClass();
}
else {
System.out.println("else");
}

return myClass;
}
}
 
S

Shawn

Very sorry! I indeed forgot "= null;" initialization. (I initialized
several local variables to null and I missed this one.)

Great. It is working and cleared my mind a little. Thank you all for
your help. I greatly appreciate it.
 

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,979
Messages
2,570,185
Members
46,721
Latest member
NelsonHeil

Latest Threads

Top