main() Functionnon-static variable cannot be referenced from a static context ErrorRemember from the Processing tutorials that you can create a class to store variables and functions in a single unit, and then you can create instances of that class using the new keyword.
Letâs say we have this class:
public class Message{
String myMessage;
public Message(String myMessage){
this.myMessage = myMessage;
}
public void printMessage(){
System.out.println(myMessage);
}
}
This code creates a Message class that contains a String variable named myMessage. It has a constructor that sets that variable, and a printMessage() function that prints it to the console.
Now we can create instances of that class using the new keyword, and we can call functions on those instances:
Message messageOne = new Message("Hello");
Message messageTwo = new Message("Bonjour");
Message messageThree = new Message("Hola");
messageOne.printMessage(); //prints Hello
messageTwo.printMessage(); //prints Bonjour
messageThree.printMessage(); //prints Hola
These variables are all of the same class, so they have the same fields and function names. But theyâre different instances, so the values of those fields are different.
The static keyword signifies that a variable or function belongs to the overall class, not to a particular instance. Itâs like the variable or function is shared between all instances of a class. Letâs look at an example.
To make a variable or function static, just add the static keyword to its declaration. This class contains a static variable and a static function:
public class StaticExample{
static int myNumber;
public StaticExample(int myNumber){
this.myNumber = myNumber;
}
public static void printNumber(){
System.out.println(myNumber);
}
}
This class contains a static variable named myNumber, and a constructor that sets that variable. It also contains a static function named printNumber() that prints the variable.
Now letâs write some code that uses this class:
StaticExample one = new StaticExample(42);
StaticExample two = new StaticExample(100);
one.printNumber();
two.printNumber();
You might expect this code to print 42 and then 100, but it actually prints out 100 twice!
This is because the myNumber variable is static, so both the one and two instances share the same value. When we pass 100 into the constructor and set the myNumber variable, weâre setting it for the whole class, not a particular instance. Furthermore, the printNumber() function is also static, so even though it looks like weâre calling functions on two different instances, weâre actually just calling the same class-level function twice.
This is confusing, which is why you should never access a static variable or function using an instance. Instead, always use the class name!
With that rule in mind, our StaticExample.java file should look like this:
public class StaticExample{
static int myNumber;
public StaticExample(int myNumber){
StaticExample.myNumber = myNumber;
}
public static void printNumber(){
System.out.println(StaticExample.myNumber);
}
}
Notice that weâre using StaticExample.myNumber to make it obvious that itâs a static variable. Now we can see that the constructor is really setting a class-level variable, not an instance variable. The rest of our code would look like this:
StaticExample one = new StaticExample(42);
StaticExample two = new StaticExample(100);
StaticExample.printNumber();
StaticExample.printNumber();
Now itâs more obvious that weâre really just calling the same function twice in a row.
main() FunctionNow you understand what the static part of the main() function means. It means that the main() function doesnât belong to any paticular instance. It belongs to the class itself.
You can put code inside the main() function that creates instances of the class. Putting it all together, hereâs the above example in a single class file:
public class Message{
String myMessage;
public Message(String myMessage){
this.myMessage = myMessage;
}
public void printMessage(){
System.out.println(myMessage);
}
public static void main(String[] args){
Message messageOne = new Message("Hello");
Message messageTwo = new Message("Bonjour");
Message messageThree = new Message("Hola");
messageOne.printMessage(); //prints Hello
messageTwo.printMessage(); //prints Bonjour
messageThree.printMessage(); //prints Hola
}
}
Try compiling and running this class! If it seems confusing, try thinking about the main() function separately from the rest of the class.
myMessage, which is set by the constructor. Then the class contains a non-static printMessage() function that prints the myMessage variable.main() function creates three instances of the Message class, and then calls the printMessage() function on each instance.All of this might not seem very useful other than explaining what the static part of the main() method means. But static variables and functions can be useful when you want to share data between instances, or when you donât want to tie a variable or function to a particular instance.
Note that youâve already been using a static variable! The System class has a static variable named out, which is an instance of the PrintStream class, which contains a println() function. Look it up in the Java API!
Letâs add a static variable and function to our Message class:
public class Message{
static int instanceCount = 0;
String myMessage;
public Message(String myMessage){
this.myMessage = myMessage;
Message.instanceCount++;
}
public void printMessage(){
System.out.println(myMessage);
}
public static void printInstanceCount(){
System.out.println("There are " + Message.instanceCount + " instances of Message.");
}
public static void main(String[] args){
Message messageOne = new Message("Hello");
Message messageTwo = new Message("Bonjour");
Message messageThree = new Message("Hola");
messageOne.printMessage(); //prints Hello
messageTwo.printMessage(); //prints Bonjour
messageThree.printMessage(); //prints Hola
Message.printInstanceCount(); //prints 3
}
}
Try compiling and running this class! If it seems confusing, try thinking about the main() function separately from the rest of the class.
myMessage and a static variable named instanceCount. The constructor sets the myMessage variable and increments the instanceCount variable. Then the class contains a non-static printMessage() function that prints the myMessage variable, and a static printInstanceCount() function that prints the instanceCount variable.main() function creates three instances of the Message class, calls the printMessage() function on each instance, and then calls the printInstanceCount() statically by using the class name.In this example, the instanceCount variable holds the total number of instances of the Message class, which isnât particular to any one instance of the class, so we make it static. Similarly, the printInstanceCount() function isnât different between instances, so we make it static as well.
It might seem confusing to have a main() function inside a class that creates instances of that class. Just remember that the main() function is static, so itâs âoutsideâ any particular instance. It might be easier to understand if you put the main() function inside a different class.
Letâs start with the first class:
public class Message{
static int instanceCount = 0;
String myMessage;
public Message(String myMessage){
this.myMessage = myMessage;
instanceCount++;
}
public void printMessage(){
System.out.println(myMessage);
}
public static void printInstanceCount(){
System.out.println("There are " + instanceCount + " instances of Message.");
}
}
Save this to a file named Message.java. This is the same class weâve been looking at. Notice that it doesnât have a main() method, so you canât run it.
Now letâs create another class that contains a main() method that uses our first class:
public class MessageMain{
public static void main(String[] args){
Message messageOne = new Message("Hello");
Message messageTwo = new Message("Bonjour");
Message messageThree = new Message("Hola");
messageOne.printMessage(); //prints Hello
messageTwo.printMessage(); //prints Bonjour
messageThree.printMessage(); //prints Hola
Message.printInstanceCount(); //prints 3
}
}
Save this to a file named MessageMain.java. This class just contains a main() method with the same code weâve been running. Hopefully this makes the code a little easier to think about.
Now youâve got two files: Message.java and MessageMain.java. You need to compile both of these classes. You have a couple ways to do that:
MessageMain.java by typing javac MessageMain.java and pressing enter. The compiler will see that the MessageMain class uses the Message class, so it will automatically compile both files.javac *.java and pressing enter. This tells the compiler to compile every file that ends with a .java extension.Either way, you should end up with two more files: Message.class and MessageMain.class. Since our main() function is inside the MessageMain class, thatâs the one we want to run by typing java MessageMain and pressing enter.
Most Java applications will use a bunch of different class files, and itâs pretty normal to have an âentry pointâ class that contains just a main() function that uses other classes.
non-static variable cannot be referenced from a static context ErrorLetâs looks at this example program:
public class Cat{
String name = "Stanley";
public static void main(String[] args){
Cat catOne = new Cat();
catOne.name = "Fluffy";
Cat catTwo = new Cat();
catTwo.name = "Professor Meow";
System.out.println("First cat's name: " + catOne.name);
System.out.println("Second cat's name: " + catTwo.name);
}
}
This Cat class contains one instance (non-static) variable called name, with a default value of "Stanley". Then the main() function creates two instances of the Cat class, giving each of them their own value for the name variable. Finally, this code will print out two different names, because each instances of Cat has its own name value.
All of that is good so far. But I promise that you will eventually write code that looks like this:
public class Cat{
String name = "Stanley";
public static void main(String[] args){
System.out.println(name);
}
}
If you try to compile this class, youâll get a compiler error:
Cat.java:6: error: non-static variable name cannot be referenced from a static context
System.out.println(name);
^
1 error
This error is telling you that youâre trying to use a non-static variable (in this case, the name variable) from a static function (in this case, the main() function). You canât access non-static variables from static functions, so the compiler gives you this error.
This might sound confusing, but think about it this way: when you type the name variable, youâre asking for a particular catâs name. But you havenât specified which instance to use, so the compiler is saying âI canât give you a catâs name if you donât tell me which catâs name you want!â
To fix this error, you might be tempted to make the name variable static, like this:
public class Cat{
static String name = "Stanley";
public static void main(String[] args){
System.out.println(name);
}
}
Donât do this! Making the name variable static will fix this particular error, but it completely breaks the point of instance variables. What would happen if we tried to create multiple instances of this class?
public class Cat{
static String name = "Stanley";
public static void main(String[] args){
Cat catOne = new Cat();
catOne.name = "Fluffy";
Cat catTwo = new Cat();
catTwo.name = "Professor Meow";
System.out.println("First cat's name: " + catOne.name);
System.out.println("Second cat's name: " + catTwo.name);
}
}
Now both cats will have the same name, because the name variable is not particular to any one instance.
Instead of making the name variable static, what we probably should have done is created an instance of Cat and got the name function that way:
public class Cat{
String name = "Stanley";
public static void main(String[] args){
Cat cat = new Cat();
System.out.println(cat.name);
}
}
Or we should have moved our logic into a function in the Cat class and used that instead of putting logic in the main() method:
public class Cat{
String name = "Stanley";
public void printName(){
System.out.println(name);
}
public static void main(String[] args){
Cat cat = new Cat();
cat.printName();
}
}
This code works, because the main() method is creating an instance of the Cat class, and then calling the printName() function of that instance. The printName() function is non-static, so it can access the non-static name variable.
Letâs look at another example. Letâs say we have two classes. First, we have a Main class:
public class Main{
String message;
public Main(String message){
this.message = message;
}
public void runProgram(){
MessagePrinter mp = new MessagePrinter();
mp.printMessage();
}
public static void main(String[] args){
Main main = new Main("Happy Coding");
main.runProgram();
}
}
This class contains one variable named message, which is set by the constructor. It also has a runProgram() function that creates an instance of MessagePrinter (which weâll see in a second) and calls its printMessage() function. The main() function just creates an instance of Main, passing in a String value, and then calls the runProgram() function on that instance.
Now we try to create a MessagePrinter class whose job it is to print the message variable from the Main class. How would we do that?
public class MessagePrinter{
public void printMessage(){
//I want to print the message variable from the Main class!
}
}
Again, you might be tempted to make the message variable static, so you could do this:
public class MessagePrinter{
public void printMessage(){
System.out.println(Main.message);
}
}
Donât do this! Again, this completely defeats the purpose of instance variables. What if you eventually want to have more than one instance of the Main class?
Instead, you need to pass the data from the Main class to the MessagePrinter class. For example, you could add a parameter to the printMessage() function:
public class MessagePrinter{
public void printMessage(String message){
System.out.println(message);
}
}
Then the Main class could pass its message variable in as an argument:
public void runProgram(){
MessagePrinter mp = new MessagePrinter();
mp.printMessage(message);
}
Another option is to pass the instance of Main into the MessagePrinter class. You could pass it as an argument to the constructor:
public class MessagePrinter{
Main main;
public MessagePrinter(Main main){
this.main = main;
}
public void printMessage(){
System.out.println(main.message);
}
}
Now the MessagePrinter class has an instance of Main, so it can get to the message variable that way. (Better yet, you could use a getter function instead. See the Access Modifiers section below.)
Now when the Main class creates an instance of MessagePrinter, it needs to pass a reference to itself into the constructor. We can use the this keyword for that!
public void runProgram(){
MessagePrinter mp = new MessagePrinter(this);
mp.printMessage();
}
You should never use the static keyword because you think it gets rid of errors or because you think itâs easier to pass data between classes. Use the above approaches instead!
As your programs get more complicated and you start using more class files, you might want to split them up into packages. Packages are collections of related classes, and they let you organize your files into folders.
Using a package is really two things:
.java files into folders.Letâs look at a concrete example. Letâs say we want to create a set of .java files inside a folder structure, like this:
In other words, we have a single directory named MyZoo that holds our whole program. The MyZoo folder contains two other folders: main and animals. The main folder contains a single file named Main.java. The animals folder contains a file named Zoo.java, and two sub-folders named mammals and reptiles. The mammals folder contains a Cat.java file, and the reptiles folder contains a Dinosaur.java file.
Letâs start with the Cat.java file:
package animals.mammals;
public class Cat{
public void meow(){
System.out.println("Meow!");
}
}
The only interesting thing here is the first line at the top. This is a package declaration, and it should always be the first line in a file. This line tells Java that the Cat class is inside the animals.mammals package, which matches the .java file being inside the animals/mammals subdirectory.
Similarly, Dinosaur.java has a package declaration putting it in the animals.reptiles package:
package animals.reptiles;
public class Dinosaur{
public void roar(){
System.out.println("Roar!");
}
}
The Zoo.java file is a little more interesting:
package animals;
import animals.mammals.Cat;
import animals.reptiles.Dinosaur;
public class Zoo{
Cat cat = new Cat();
Dinosaur dinosaur = new Dinosaur();
public void visit(){
System.out.println("Let's visit the cat.");
cat.meow();
System.out.println("Let's visit the dinosaur.");
dinosaur.roar();
}
}
This code starts with a package declaration saying itâs in the animals package. Then it imports our first two classes using their package and class names. That lets us use those classes inside the Zoo class.
Finally, our Main.java file does something similar:
package main;
import animals.Zoo;
public class Main{
public static void main(String[] args){
Zoo zoo = new Zoo();
System.out.println("Let's go to the zoo!");
zoo.visit();
System.out.println("That was a fun day at the zoo.");
}
}
This code starts with a package declaration, then imports the animals.Zoo class. Then it contains a main() method that uses the Zoo class. Hooray! ![]()
To compile this program, weâd open a command prompt to the top-level MyZoo directory. From there, weâd type javac main/Main.java to compile the Main.java class. Since this class uses the Zoo class, which uses Cat and Dinosaur classes, compiling Main.java causes every class to be compiled. But note that you have to do this from the top-level MyZoo directory!
Now that weâve compiled our classes, we can run our program by typing java main.Main and pressing enter. Note that we also have to do this from the top-level MyZoo directory, and notice that we use dots instead of slashes!
The whole process looks like this:

You might have noticed the public keyword in some of our code. Thatâs called an access modifier, which tells Java who can access a member (a variable or function).
There are a few access modifiers:
public members can be accessed by any class.private members can only be accessed by that class.protected members can be accessed by classes in the same package or by subclasses (itâs okay if you donât know what this means yet).This might not seem useful for simple code or code that only you work on. But it becomes really important if youâre writing code with other people!
Usually, most variables are private, and only the constructors and functions that other people should use are public.
For example, letâs say you and another person are working together, with a goal of creating a program that only prints out three things. You split the work up: youâll create a class that contains the logic for counting the things that have been printed, and the other person will pass data into your class.
So, you write your code:
public class PrintThreeTimes{
int timesPrinted = 0;
public void print(String thing){
if(timesPrinted < 3){
System.out.println(thing);
timesPrinted++;
}
else{
System.out.println("Sorry, I can't print anything else.");
}
}
}
This code works, and the print() function will only print the parameter three times. After that it will print an error message.
Now, your partner comes along and writes this code, which uses your class:
public class SomebodyElsesCode{
public static void main(String[] args){
PrintThreeTimes ptt = new PrintThreeTimes();
ptt.print("thing one");
ptt.print("thing two");
ptt.print("thing three");
ptt.print("thing four");
}
}
This correctly prints out three things and then an error message:
thing one
thing two
thing three
Sorry, I can't print anything else.
However, your partner wasnât really paying attention, and they think that the goal was to print four things instead of three! They know they arenât supposed to change the code you wrote, but they also see that the timesPrinted variable is not private. This tells them that they are supposed to change that variable. So they modify their code:
public class SomebodyElsesCode{
public static void main(String[] args){
PrintThreeTimes ptt = new PrintThreeTimes();
ptt.print("thing one");
ptt.print("thing two");
ptt.print("thing three");
ptt.timesPrinted = 0;
ptt.print("thing four");
}
}
Now this code âworksâ and allows four things to be printed, and your partner submits it. If this is a school assignment, now youâre getting a bad grade. If this is a work assignment, now youâre getting fired! And it could have been avoided if you had simply made the timesPrinted variable private in the first place:
public class PrintThreeTimes{
private int timesPrinted = 0;
public void print(String thing){
if(timesPrinted < 3){
System.out.println(thing);
timesPrinted++;
}
else{
System.out.println("Sorry, I can't print anything else.");
}
}
}
Now nobody else can touch the timesPrinted variable, and theyâll get a compiler error if they try. This tells them that they arenât supposed to modify the value of the variable. In this example, maybe this causes your partner to read the instructions again, or maybe they ask you about it. Either way, you end up with a better grade and you arenât fired!
If you want to allow other people to know the value of a variable but not change it, you can use a getter function that just returns the value of the variable:
public class PrintThreeTimes{
private int timesPrinted = 0;
public int getTimesPrinted(){
return timesPrinted;
}
public void print(String thing){
if(timesPrinted < 3){
System.out.println(thing);
timesPrinted++;
}
else{
System.out.println("Sorry, I can't print anything else.");
}
}
}
Now your partner can get the value of the variable, so they can check when the limit has been reached. But they canât set the value of the variable, so they canât get you fired.
This is admittedly a dumb example, but itâs not that far-fetched: a ârealâ program that only has a limited number of connections to a database might use code almost exactly like this.
Real code is going to be much more complicated, so get in the habit of marking your variables private now.
This was a bit of an information dump, but youâre going to see all of the above sooner rather than later. Processing hid a lot of these details from you, but you need to understand whatâs going on behind the scenes when youâre programming in Java.
You donât have to memorize the stuff in this tutorial. Instead, try to keep the general principles in mind:
static, but donât misuse it to pass data between classes.private.And if you find yourself needing to remember a particular detail (how do I pass data between classes again?), then come back here and read the tutorial again.