13
public class Bicycle {

    private int cadence;
    private int gear;
    private int speed;
    private int id;
    private static int numberOfBicycles = 0;

    public Bicycle(int startCadence, int startSpeed, int startGear){
        gear = startGear;
        cadence = startCadence;
        speed = startSpeed;

        id = ++numberOfBicycles;
    }
       // ...
}

I learned in my class that Static variables should be accessed by calling with class name. i.e. ClassName.VariableName

But in the code above, how is this statement id = ++numberOfBicycles; compiled without errors, even though the variable numberOfBicycles is static

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
Testaccount
  • 2,755
  • 3
  • 22
  • 27
  • 3
    From outside the class, "static variables should be accessed by calling with class name." From the inside, the class qualification is inferred by the compiler. – Dek Dekku Jun 02 '13 at 06:19
  • 3
    Note that this line `id = ++numberOfBicycles;` is not thread safe – Steve Kuo Jun 02 '13 at 16:41

8 Answers8

22

Static variables are owned by class rather than by its individual instances (objects). Referring static variables outside the class is by ClassName.myStaticVariable but inside the class it is similar to other instance variables.

You can always use static variables in non-static methods but you cannot use non-static variables in static methods reason being when static methods are loaded other non-static instance variables are not created.

So your statement id = ++numberOfBicycles; is perfectly valid and will compile without errors.

Jianxin Gao
  • 2,717
  • 2
  • 19
  • 32
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
7

From within the class the Bicycle qualifier is optional on static variables, just like the this qualifier is optional on instance variables

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • But what's the Fully Qualified way of resolving this? It's like you _can_ omit `this.` but it's frowned upon. What's the actual way of referring to yourself in Java. In PHP you'd use `static::` or `self::`. – Elven Spellmaker Jul 26 '21 at 23:05
5

May be what your lecturer said is regarding accessing them from outside the class not from inside the class. static variables can be accessed outside the class like this ClassName.VariableName or object.VariableName. But however the first method is preferrable.

From inside the class it's not needed you may use this keyword or classname-qualifier to disambiguate with the local variables with the same name inside methods and constructors.

pinkpanther
  • 4,770
  • 2
  • 38
  • 62
5

Static variables are the shared variables. So you can access them using either the Classname.staticVariable or using an object of the class instance.staticVariable. In any case you will be referring to the single copy of the variable in memory, no matter how many objects you create.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
2
 public int getID(){
    return numberOfBicycles;
}

public static int getNOB(){
    return numberOfBicycles;
}


In the Bicycle class

    Bicycle bc = new Bicycle(30, 90, 1);
    System.out.println(Bicycle.getNOB());
    System.out.println(bc.getID());

    Bicycle bc2 = new Bicycle(30,90, 1);
    System.out.println(Bicycle.getNOB());
    System.out.println(bc2.getID());

    Bicycle bc3 = new Bicycle(30,90, 1);
    System.out.println(Bicycle.getNOB());
    System.out.println(bc3.getID());

    Bicycle bc4 = new Bicycle(30,90, 1);
    System.out.println(Bicycle.getNOB());
    System.out.println(bc4.getID());


In the main class of BicycleTest worked just fine for me

Manny265
  • 1,709
  • 4
  • 23
  • 42
1

Given your class ..

public class Bicycle
{
    private int cadence;
    private int gear;
    private int speed;
    private int id;
    private static int numberOfBicycles = 0;

    // ..
}

When I create an objects of type Bicycle, it will be like this:

Bicycle a = new Bicycle (1,2,3);

Bicycle b = new Bicycle (2,3,4);

In memory, it's like this:

[a] --> { id:1, cadence:1, gear:2, speed:3 }

[b] --> { id:2, cadence:2, gear:3, speed:4 }

numberOfBicycles is static, so it's not part of any Bicycle object, it's related to the class not an object, and so it will be like this in memory:

[Bicycle] --> { numberOfBicycles:2 }

And so to access the static member, first we define a static getter for it:

public static int getNumberOfBicycles ()
{
    return numberOfBicycles;
}

then we call it from the class:

System.out.println(Bicycle.getNumberOfBicycles());
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
1

Non static methods can access static members of a class because only a single copy of the static variable exists unlike instance variables which are only created once a new object of that type has been created.
I recommend you have another class to test,like BicycleTest which will have the main class and then create maybe 4Bicycle objects and using 2getters in the Bicycle class retrieve the numberofBicycles and ID everytime you create an object maybe that will give you a picture of what is happening.

Manny265
  • 1,709
  • 4
  • 23
  • 42
1

you didn’t write Bicycle.numberOfBicycles. It isn’t necessary because we are already in that class so the compiler can infer it.

bassam
  • 11
  • 1