I am trying to create an item list, diffrent for each i and j variable. My code is:
if (i == 0) {
if (j == 0) {
final CharSequence[] items = {"4:45", "5:00"}
} else if (j == 1) {
开发者_开发问答 final CharSequence[] items = {"4:43", "4:58"}
} else if (j == 2) {
final CharSequence[] items = {"4:41", "4:56"}
} else {
final CharSequence[] items = {"4:38", "4:53"}
}
...
new AlertDialog.Builder(this)
.setTitle("Hours")
.setItems(items,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface, int i) {
// getStation(i);
}
})
.show();
}
I get an error in the line .setItems(items,
:
items cannot be resolved
I think that the compiler thinks that the CharSequence[] items
may not be initialised or something...
How can I make this programme run?
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.
Because you define (as well as give a value to) items
within a block, it is only visible within that block. Pull the definition out of the block to somewhere visible to both the snippets you have given us, and just assign a value within the if
else
construct.
Declare items
before the
if (i == 0) {
The way you are doing it now, items
is only in scope inside you inner if
s.
You are only declaring items in local scope. You need to move the
final CharSequence[] items
outside the if clauses and the instantiate it inside the if clause.
精彩评论