6

I'm learning Java and I'm getting this error. I know this has been asked a few (a lot of) times but none of the answers seems to answer my question. The body of the code is:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
int i;
if(num<1){
 i=0;
}
if(num==1){
 i=1;
}
if(num==2){
 i=2;
}
if(num==3){
 i=3;
}
if(num==4){
 i=4;
}
if(num>4){
 i=5;
}
return number[i];

where the variable 'num' is declared, initialized and given previously. The error I get is: "Variable 'i' might not have been initialized" and pointing to the last line (return number[i];).

The thing is, if I declare 'i' and immediately assign a value (int i=0;) the code runs fine. But if I don't assign a value I get the error EVEN if a possible value is assigned after each 'if'.

I don't get this kind of error with C, for example.

Thanks

asked Jun 10, 2014 at 23:15
6
  • The compiler tells you it wants you to assign a value; obviously when you do that it will work. Why don't you want to do this? Commented Jun 10, 2014 at 23:17
  • 1
    rgettman explained this well. My preferred fix would be to (1) use else on all the branches, and (2) make the last one an else without another if, i.e. else { ... instead of else if (num > 4) { .... I think that makes things clearer to a reader as well as avoiding the "definite assignment" problem. In this particular case, I'd just write int i = (num < 1) ? 0 : (num > 4) ? 5 : num;. Commented Jun 10, 2014 at 23:28
  • 1
    @ajb The ternary coniditoinal seems too convoluted here. I'd just an else :| Commented Jun 10, 2014 at 23:28
  • @JeroenVannevel It does work but I want to know why it doesn't work in other ways. Commented Jun 10, 2014 at 23:29
  • This chapter of the jls defines the rules for definite assignment. Commented Jun 10, 2014 at 23:33

3 Answers 3

12

Java doesn't analyze the logic of your if blocks determine that one of your if statements will run and assign a value to i. It is simple and it sees the possibility of none of the if statements running. In that case, no value is assigned to i before it's used.

Java will not give a default value to a local variable, even if it gives default values to class variables and instance variables. Section 4.12.5 of the JLS covers this:

Every variable in a program must have a value before its value is used:

and

A local variable (§14.4, §14.14) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26)

Assign some kind of default value to i, when you declare it, to satisfy the compiler.

int i = 0;
// Your if statements are here.
return number[i];
answered Jun 10, 2014 at 23:18
Sign up to request clarification or add additional context in comments.

8 Comments

I do not recommend using a default assignment in most cases as I find that it can hide issues - i.e. forgetting to handle some logic. Instead, I usually use an appropriate else where it is more explicit and clear of intent (e.g. the correct solution could also be to return early or throw an exception).
@user2864740 I agree with you in this case. However, I've run into cases involving loops where I can tell that a variable will always be assigned before the loop exits, but there's no good way to rearrange the code to convince the compiler of that. I do see that you said "most cases".
@user2864740 I think that either way would be valid. I've used either way (default explicit initial value plus simple else), depending on which is more readable and more clear in that case.
@rgettman Strangely enough, the code works when I use 'else if(...)' for 2-4 and else{...} for 5, without initializing the variable 'i' at the beginning. Just as if Java doesn't assume that all possibilities are comprised in multiple 'if', but it understand that all possibilities are comprised in one 'if' and multiple 'else'.
@rgettman I'm not trying to say a default assignment is wrong by any means (and this answer is certainly correct) - it's just not my "go to" to fix this compiler error.
|
0

If you wanted to clean up the code, you could very easily do this:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
int i = num;
if (i < 1) { i = 0; }
if (i > 4) { i = 5; }
return number[i];

Or if the value of num doesn't even matter:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
if (num < 1) { num = 0; }
if (num > 4) { num = 5; }
return number[num];

Even if the code you had before seemed okay logically, the compiler can't always compete with human intelligence. Giving it that default value will help to satisfy the safety of your method.

answered Jun 10, 2014 at 23:46

Comments

-1

Make the code in line 2 to:

 int i = 0.00

As java needs a value beforehand when you create the variable. I hope it works fine after that:)

answered Mar 31, 2024 at 23:56

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
The OP is saying the same thing in the question itself. No need to echo that.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.