Variable cannot be resolved

You actually have 4 items variables in your code, each one with a very limited scope (only the code-block of the respective if).

Instead you'll want to create one variable with a bigger scope:

if (i == 0) { 
            final CharSequence[] items;
            if (j == 0) { 
                items = new CharSequence[] {"4:45", "5:00"};
            } else if (j == 1) { 
                items = new CharSequence[] {"4:43", "4:58"};
            } else if (j == 2) { 
                items = new CharSequence[] {"4:41", "4:56"};
            } else { 
                items = new CharSequence[] {"4:38", "4:53"};
            }
            // you can use items here
}

Edit: I forgot that the new CharSequence[] is necessary here. You can leave it out if you initialize the variable during declaration, but here you moved the declaration out and use a simple assignment to set a value. For some reason the short syntax of defining an array is only valid in an initializaton statement (i.e. in an assignment that is in the same statement as the declaration).


The problem is variable scoping.

if (someCondition) {
   final int i = 666;
} else {
   final int i = 42;
}
int j = i + 1; // compile-time error

Here we have two local variables i who goes out of scope immediately after they're declared and initialized. If j needs the value of i, then i would have to be declared in a larger scope.

final int i;
if (someCondition) {
   i = 666;
} else {
   i = 42;
}
int j = i + 1; // compiles fine!

(It should be mentioned that this is exactly the kind of scenarios where the ternary operator excels, i.e.)

final int i = (someCondition) ? 666 : 42;

In your specific case, unfortunately the array initializer shorthand can only be used to initialize upon declaration. That is:

int[] arr1 = { 1, 2, 3 }; // compiles fine!
int[] arr2;
arr2 = { 4, 5, 6 }; // doesn't compile!

You can pull out the declaration of items outside the if and write the verbose code for each case (see Joachim Sauer's answer), but a more concise code is to use array-of-arrays instead.

final CharSequence[][] allItems = {
   { "4:45", "5:00" },
   { "4:43", "4:58" },
   { "4:41", "4:56" },
   { "4:38", "4:53" }
};
final CharSequence[] items = allItems[j];

This technique works well in this case, but in the more general case you want to use a Map or something similar.

Note: It's not explicit in the original code, but this works if j can either be 0, 1, 2, or 3. If you want the last option to apply when j is any value other than 0, 1, 2, then you have to check for that and set it to 3 before this code.


In Java you have strict block-level scope, so for example:

if (blah) { int foo = 1; }
// foo is no longer visible here

So once you reach that closing curly brace } your items variable is no longer visible. This is different from JavaScript for example where you have function-level scope.

Hope this helps.