-4

I'm writing a simple money tracker as a practice project. Here is a shortened version of my code:

public class MoneyTracker {
    float salary1;

    public void enterSalary1(float newValue){
        salary1 = newValue;
    } 

    public static void main(String[] args) {
        MoneyTracker monthlySpend = new MoneyTracker();
        monthlySpend.enterSalary1(1385.50f);
        System.out.println(salary1);
    }
}

This produces the error:

non-static variable salary1 cannot be referenced from a static context. 

After reading some threads, I changed the variable to read static float salary1; which fixed the issue.

However, I have another simple program which I built following the java tutorials on the Oracle website, it has a very similar set up and as far as I can tell, should result in the same error, but this compiles and runs with no problems. The code:

public class Bicycle{

    //declare instance fields
    int gear = 1;
    int speed = 0;
    int pedalRPM = 0;

    //constructor classes

    public void changePedalRPM(int newValue){
        pedalRPM = newValue;
    }

    public void changeGear(int newValue){
        gear = newValue;
    }       

    public void speedUp(int increment){
        speed = speed + increment;
    }

    public void applyBrake(int decrement){
        speed = speed + decrement;
    }   

    public void printStates(){
        System.out.println("pedalRPM:" + pedalRPM + " speed:" + speed + " gear:" + gear);
    }

    public static void main(String[] args) {
        Bicycle bike = new Bicycle();

        bike.changeGear(2);
        bike.changePedalRPM(85);
        bike.speedUp(15);
        bike.printStates();
        bike.speedUp(5);
        bike.printStates();
    }
}

I realise there is a printStates method here which is called from inside the main method, which is the only difference, but I have tried this with my money tracker and I still get the non-static variable error.

Is anyone able to explain to me why I get two different results from relatively similar programs? It seems weird that no tutorials would mention this if the main method must be static and this is where the variables are utilised.

Edit - allow me to clarify my thinking.

In my money tracker example, I'm using equivalent code in equivalent places as the bicycle. The bicycle code is straight from Oracle so it must be a valid way of doing things.

I have:

float salary1;

in the same place as

int gear = 1;

My constructor

public void enterSalary1(float newValue){
    salary1 = newValue;
} 

is in the same place as (for example)

public void changeGear(int newValue){
    gear = newValue;
}    

I then make a new instance of the class, inside the main method:

MoneyTracker monthlySpend = new MoneyTracker();

Which is the same as

Bicycle bike = new Bicycle();

My statements are then in the same place as in the bicycle program

monthlySpend.enterSalary1(1385.50f);

is equivalent to

bike.changeGear(2);

The Bicycle program compiles and the Money Tracker does not. I do understand the answers that say I can't call a non-static variable from a static method - but it appears that one of the programs allows me to, so where is the difference?

Thanks you for all of your answers!

Itch
  • 1
  • 1
  • The problem in your code is `System.out.println(salary1);`. That line occurs in the static methof `main` but because `salary1` is non-static it exists only in the context of an instance of `MoneyTracker`. In that line you're not refering to any such instance, hence the compiler doesn't know where to get the value from. It should compile if you'd change that to `System.out.println(monthlySpend.salary1);` because now the compiler know to take `salary1` from the instance `monthlySpend`. – Thomas Mar 19 '19 at 11:19
  • Try `System.out.println(gear);` in your second example, you will get the same error . – Arnaud Mar 19 '19 at 11:20
  • Your solution, to change it into static, was *wrong*, what you should do is add a getter to your class and print using that getter. – RealSkeptic Mar 19 '19 at 11:20

3 Answers3

0

It is because main method is static and you try to reference non-static field (salary1) in there, doing System.out.println(salary1). In the second example you are not referencing any non-static field in static main method, thats why there is no error. Use getters/setters. Hope I helped :)

M. Wojcik
  • 2,301
  • 3
  • 23
  • 31
0

This is very simple.

In the first example, you are building your variable salary1 outside of the static method.

In the second example, you are building your variable, which is bike and not the Bike class as a whole, inside the static method.

Mwak
  • 106
  • 6
0

I encountered the same issue when I started with Java, then I putted static everywhere, which was the wrong choice!

Your "static context" is your static method main (be aware of the "static" keyword before the method name). A static method is not an object's method but a class's method. A static method can only access to class's fields (fields prefixed with static keyword), these kind of fields is shared between all objects of this class.

For example, try that:

public class Counter {
    private static int cpt = 0;

    public int incr() {
        cpt = cpt + 1;
        return cpt;
    }

    public static void main(String args[]) {
        Counter counter1 = new Counter();
        Counter counter2 = new Counter();
        System.out.println(counter1.incr()); // print 1
        System.out.println(counter2.incr()); // print 2
    }
}

Here, even I called only once "incr" on "counter2", it returns "2" because "cpt" is shared between counter1 and counter2.

So, how to solve your issue. You must access object's field (aka instance's field) throw an instance identifier like "counter1.cpt" or in an object's method (like the "incr()" one). Here a fix of your first class:

public class MoneyTracker {
    float salary1;

    public void enterSalary1(float newValue){
        salary1 = newValue;
    } 

    public static void main(String[] args) {
        MoneyTracker monthlySpend = new MoneyTracker();
        monthlySpend.enterSalary1(1385.50f);
        System.out.println(monthlySpend.salary1);
    }
}

hoping it will help you.

6pi
  • 387
  • 2
  • 11