Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java only allowing global variables to be static?

So I just started coding a Java program I'm writing and it's telling me that my global variables need to be static. I don't understand why it's telling me this because I've developed Java programs before without having to make my global variables static. Could someone please help?

 import java.awt.event.*;
 import javax.swing.*;

 public class PlannerMain {
      JFrame frame;
      JButton makeMap;

      public static void main(String[] args){
           frame = new JFrame("Land Planner");
           makeMap = new JButton("Make Map");
           makeMap.addActionListener(new makeMapListener());
           frame.setSize(580,550);
           frame.setVisible(true);
      }

      class makeMapListener implements ActionListener{

              public void actionPerformed(ActionEvent e) {

              }
      }

}
like image 532
TomLisankie Avatar asked Feb 05 '11 21:02

TomLisankie


3 Answers

Your main method is static, so it can access only the static fields of the class directly. Otherwise, you need to create an instance of PlannerMain first, then you can access its fields. I.e.

public static void main(String[] args){
  PlannerMain planner = new PlannerMain();
  planner.frame = new JFrame("Land Planner");
  planner.makeMap = new JButton("Make Map");
  planner.makeMap.addActionListener(new makeMapListener());
  ...
}

Note that such initialization code is better put in a constructor method.

Btw the variables you refer to are not global. Right now you have as many distinct frame and makeMap as many instances of PlannerMain you create. They would only be "global" (or its closest equivalent in Java) if you declared them public static - in this case all PlannerMain instances would share the same frame and makeMap, and the external world would see them as well.

like image 69
Péter Török Avatar answered Oct 03 '22 20:10

Péter Török


There are no global variables in Java in the meaning of variables which would be valid in the whole program.

There are

  • class variables: These are most similar to what are called "global" variables in other languages. They are declared inside a class with the static keyword. There is only one variable for the whole class. (If the class would be loaded again with another classloader, this new class would have new variables, of course.)

    They should be used prefixed with the class: MyClass.varName. Inside of the class you also can omit the prefix, and you also could use them prefixed with an object of that type (but this is discouraged).

  • instance (or object) variables: These are what you have in your example: anything declared inside a class (and outside of any method/constructor/block) without the static keyword is a instance variable. For each object of the containing class (which includes objects of any subclasses of this class) there is exactly one variable. (From the "state" view, one could say an object consists of all its instance variables + an identity.)

    They are used prefixed by an object (of the right type): myObject.varName. Inside of non-static methods of this class you can use them unprefixed (this is then referring to the variables of the current object).

  • local variables: These are all variables declared inside of a method or a constructor (or block). They exist once for each invocation of this method, and cease to exist after the method finished. They can only be accessed from inside this method/block, not from methods called from there.

    Special cases of these are method/constructor parameters and catch-block-parameters.

  • array elements: Every element of an array is a variable of the same type. They can be used everywhere where one has a reference to this array (often in one of the other types of variables), using an index in brackets.

So, in your case you have object variables, and want to use them from a class method (static method). A class method has no current object, thus you have to qualify your variables with an object to use them. Depending on what you want, it may be useful to write it this way:

import java.awt.event.*;
import javax.swing.*;
 
public class PlannerMain {
   JFrame frame;
   JButton makeMap;
   
   void initGUI() {
     frame = new JFrame("Land Planner");
     makeMap = new JButton("Make Map");
     makeMap.addActionListener(new makeMapListener());
     frame.setSize(580,550);
     frame.setVisible(true);
   }

   public static void main(String[] args){
     PlannerMain pm = new PlannerMain();
     pm.initGUI();
   }
}
like image 31
Paŭlo Ebermann Avatar answered Oct 03 '22 19:10

Paŭlo Ebermann


In java the entry point - the main method must be static, therefore any class variables it accesses must also be static.

To avoid having static member variables spawn out all over the code (which is bad) from this do the following:

public class PlannerMain {

 JFrame frame;

 JButton makeMap;

 public static void main(String[] args){
     PlannerMain theApp = new PlannerMain();
     theApp.init();
 }

 private void init() {
     frame = new JFrame("Land Planner");
     makeMap = new JButton("Make Map");
     makeMap.addActionListener(new makeMapListener());
     frame.setSize(580,550);
     frame.setVisible(true);
 }

 class makeMapListener implements ActionListener{

    public void actionPerformed(ActionEvent e) {



        }

    }
}

Now your static main method creates a concrete (non-static) instance of your PlannerMain class so it can use the member variables.

like image 43
Alb Avatar answered Oct 03 '22 19:10

Alb