5

When declaring my variables at the beginning of the class, I can't use them in a conditional statement in other methods. I tried declaring them inside the method it works but I can't use the variables outside the method.

This is a sample of my code

protected void onClick(View v){
  switch(v.getId()){        
    int counter;
    case R.id.btsend:
      for (int i = 0;i<=0;i++){          
        if (true)
          counter += 1;          
      }

    TextView.setText(counter);

    break;
  }
}
peterh
  • 11,875
  • 18
  • 85
  • 108

3 Answers3

11

There's no "one size fits all" answer here because there are different reasons for declaring variables.

Static variables (declared directly within the class, with the static modifier) are class-wide, rather than specific to a single instance. Usually static variables are final - mutable global state is a tricky business.

Instance variables (declared directly within the class) are there to record the state of the object. They will be available within every instance method.

(Instance and static variables are both fields.)

Local variables (declared within a constructor or method) are only available within that method, and are effectively "temporary" data which is only required for that single method invocation. (If the method is called recursively, each call gets its own independent set of variables.)

So for each variable, consider whether it's logically part of the state of the object or not, and declare it in the appropriate place. Once you've decided what kind of variable it is, you can then determine the physical placement. For fields, it doesn't matter (much) exactly where you declare it - at the top of the file, in the middle, or at the bottom. The ordering between fields matters in terms of initialization, but it doesn't matter whether it's before or after a method that uses it. It's generally a good idea to declare all your fields in one consistent place though - personally I usually have:

class Foo
{
    // Static variables
    // Instance variables
    // Constructors
    // Methods
    // Nested types
}

... but that's just a convention.

For local variables, it's generally a good idea to declare them as late as possible, within as small a scope as possible. So instead of:

int i;
int x;
for (i = 0; i < 10; i++) {
    x = i * i;
    System.out.println(x);
}

This would be preferrable:

for (int i = 0; i < 10; i++) {
    int x = i * i;
    System.out.println(x);
}

By limiting the scope of a variable, it's typically easier to reason about it.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 12
    Hang on, I have to take a screen dump. Skeet's photo next to an answer with -1. Nobody upvote this for the next 20 seconds please! – Dawood ibn Kareem Apr 11 '14 at 08:27
  • 1
    I have a confession to make. I disobeyed my own request, and upvoted this answer immediately after posting my earlier comment. So I have no screen dump of it. More importantly though, it's an exemplary answer - accurate, succinct and informative. Nice work Jon. – Dawood ibn Kareem Apr 11 '14 at 08:46
4

You need to declare variables

  • in a place where declarations are allowed by the Java syntax, and

  • in a place that is appropriate to the intended lifetime of ... whatever it is.

So, in your example, you can't declare counter at that point, because the syntax of a switch statement does not allow it. But you could put it before the switch statement. Or before the method, or after it.

Next you need to ask yourself how long counter is supposed to "live". If it is supposed only to live while onClick is running, then it needs to be declared inside the onClick method. But if it is intended to live as long as the instance of the object ... then it should be an instance variable ... and declared at the top of the class.

And so on ...

In short, the correct answer depends on what you are trying to do ...


(In this case, if counter is supposed to count the number of clicks on ... "this thing" ... it probably should be an instance variable. It could also be a static variable, modulo the issue that that is likely to be a poor design choice, and it could be incorrect for other reasons. A local variable would definitely be incorrect, as a click counter.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • @Duncan Given the depth of the OP's question, I would this answer is perfect. – Scary Wombat Apr 11 '14 at 08:29
  • @Duncan - the problem is most likely that the OP has not *formed* an intention. What I'm saying is that he needs to do that; i.e. he needs to understand what he is trying to get his program to do ... *before* he he can write his code. – Stephen C Apr 11 '14 at 08:36
  • @StephenC I agree. Your revised answer is much more informative on that particular aspect. +1 – Duncan Jones Apr 11 '14 at 08:38
  • @Duncan - I write my answers incrementally. You will observe that most high rep contributors do the same. – Stephen C Apr 11 '14 at 08:39
  • @StephenC It is a pattern I've certainly noticed. I'm not sure I'm a fan of the FGITW approach, but each to their own... As long as the initial answer has sufficient info, I'm generally happy with it as a practice. – Duncan Jones Apr 11 '14 at 08:41
  • Yes, there are even those who start an answer, wait for others to answer, then copy the other respondents' ideas into their own answer. The timestamps then incorrectly show that they thought of the answer first. – Dawood ibn Kareem Apr 11 '14 at 08:41
  • @DavidWallace - SO is not a competition about who answers first. IMO upvotes should be for the best answers, not the quickest ones. But unfortunately, some people have the attention span of a .... OMG look, there's a pony!!! – Stephen C Apr 11 '14 at 08:45
  • @StephenC I didn't mean to imply that you had done any such thing. Sorry if you read it this way. This is a fine answer, and consistent with the quality of other answers of yours. I'm well aware that it's entirely your own work. And can you bring me back my pony please? – Dawood ibn Kareem Apr 11 '14 at 08:55
-2

You may declare it globally to access it anywhere you want to. To declare it globally declare it outside.

To define Global Variable you can make use of static Keyword

public class Global {
    public static int a;
    public static int b;
}

now you can access a and b from anywhere by calling

Global.a;

Global.b;

You may want to Google it if you do not know how to declare global variable

Daksh Shah
  • 2,997
  • 6
  • 37
  • 71
  • 1
    Your answer suggests that global variables are the panacea for all variable scope problems. Whereas they are often a bad idea and indicative of bad OO design. – Duncan Jones Apr 11 '14 at 08:37
  • 1
    And often, global variables simply don't work. "Here's how to use global variables" is not an appropriate answer to "where should I declare my variables", and it's disappointing to me to see that this answer has two upvotes. Now, if the question had been "where should I NOT declare my variables", I might have upvoted this myself. – Dawood ibn Kareem Apr 11 '14 at 08:57
  • @DavidWallace Why do you two have such a rotten opinion about global variables? If someone wants access to a variable everywhere then Global Variables are the one to use. I am from C background so maybe the problem lies there cause u ppl code on android/java from beginning. But why so? Why do you hate global variables so much what bad did they do to you? they are not that bad in C at least in my knowledge – Daksh Shah Apr 11 '14 at 10:24
  • 2
    If someone wants to access a variable everywhere, then they have some serious problems with the design of their program. Since C is your background, let me point you at http://stackoverflow.com/q/176118/1081110 which has many arguments against the use of global variables. And let me add some more of my own. It can be very difficult to isolate code that uses global variables, in order to unit test it. It's difficult to track which parts of a program use a global variable, which creates a maintainability nightmare. There is a huge scope for mutual dependencies, which increase complexity ... – Dawood ibn Kareem Apr 11 '14 at 10:44
  • 2
    ... and reduce maintainability. They make it difficult to integrate libraries into your program, or even to integrate the work of multiple developers together, as there is no guarantee that different authors haven't used the same global variable names. So in summary, global variables have very many problems; but even if they did not, this would not be a good answer, because you have only mentioned one type of variable. This suggests that global variables are the right answer for ALL scope problems, when the fact is that there are many different types of scope problem, and different ... – Dawood ibn Kareem Apr 11 '14 at 10:45
  • 2
    ... solutions are appropriate for each. So, umm, -1 for suggesting that there's only one kind of variable to use; and umm -1 again for advocating the one kind of variable that leads to code that is difficult to follow, difficult to maintain, and difficult to test. You asked the downvoters to explain their stance; and Duncan and I have done so. Now I would like to ask the upvoters to explain **their** stance. Where is the merit in this answer? – Dawood ibn Kareem Apr 11 '14 at 10:45
  • @DavidWallace Agreed! +1 to your comments, now tell me should I just delete the answer or is it of any any use? – Daksh Shah Apr 11 '14 at 12:42
  • Well, my opinion is that deleting it would be a fine thing to do. But that is just one man's opinion; whereas four people have upvoted this. So maybe you could leave it for a while; at least until one of them responds to my request to explain their stance. – Dawood ibn Kareem Apr 11 '14 at 18:03
  • @DavidWallace Ok. Sure – Daksh Shah Apr 12 '14 at 04:15