7

I just started learning Java and I wrote a class to test using static fields. Everything works fine but in Eclipse I see an icon which when hovered comes out as: "The static method getCounter from the type CarCounter should be accessed in a static way." What's the right way then?

Here's the class:

public class CarCounter { static int counter = 0; public CarCounter(){ counter++; } public static int getCounter(){ return counter; } } 

And here's where I try to access variable counter:

public class CarCounterTest { public static void main( String args[] ){ CarCounter a = new CarCounter(); System.out.println(a.getCounter()); //This is where the icon is marked } } 

6 Answers 6

18

Static fields and methods are not belong to a specific object, but to a class, so you should access them from the class, and not from an object:

CarCounter.getCounter() 

and not

a.getCounter() 
Sign up to request clarification or add additional context in comments.

3 Comments

replace need by should as both lines of code are correct but the second one is discouraged
This answered it for me; your answer was short at the same time concise. Amazing!
@Binyamin Sharet I know this was an older question but your comment helped me through my project. Thank you!
17

Use CarCounter.getCounter(). That makes it clear that it's nothing to do with the object that the a variable's value refers to - the counter is associated with the type itself, rather than any specific instance of the type.

Here's an example of why it's really important:

Thread t = new Thread(runnable); t.start(); t.sleep(1000); 

What does it look like that code is doing? It looks like it's starting a new thread and then "pausing" it somehow - sending it to sleep for a second.

In fact, it's starting a new thread and pausing the current thread, because Thread.sleep is a static method which always makes the current thread sleep. It can't make any other thread sleep. That's a lot clearer when it's explicit:

Thread t = new Thread(runnable); t.start(); Thread.sleep(1000); 

Basically, the ability of the first snippet of code to compile is a mistake on the part of the language designers :(

1 Comment

c# designers fixed this mistake.
9

That would be:

System.out.println(CarCounter.getCounter()); 

Comments

2

It is even possible, though highly discouraged, to write:

Math m = null; double d = m.sin(m.PI/4.0); System.out.println("This should be close to 0.5 " + (d*d)); 

This is because static accesses look at the declared type of the variable, and never actually dereference it.

Comments

0

Static elements belong to the class. Therefore, the best way to access them is via the class. So in your case, the print out should be.

System.out.println(CarCounter.getCounter());

This may feel triviaval unnecessary but it is not. Consider the following code

// VehicleCounter.java public class VehicleCounter { static int counter = 0; public VehicleCounter(){ counter++; } public static int getCounter(){ return counter; } } // CarCounter.java public class CarCounter extends VehicleCounter { static int counter = 0; public CarCounter(){ counter++; } public static int getCounter(){ return counter; } } // CarCounterTest.java public class CarCounterTest { public static void main( String args[] ){ VehicleCounter vehicle1 = new VehicleCounter(); VehicleCounter vehicle2 = new CarCounter(); System.out.println(vehicle1.getCounter()); System.out.println(vehicle2.getCounter()); } }

What should the above code prints?

The behaviour of the above code is hard to define. vehicle1 is declared as VehicleCounter and the object is actually a VehicleCounter so it should print 2 (two vehicles are created).

vehicle2 is declared as VehicleCounter but the object is actuall CarCounter. Which should be printed?

I really don't know what will be printed but I can see that it can easily be confused. So for a better practice the static elements should always be accessed via the class it defined.

It much easier to predict what to be printed by the following code.

// CarCounterTest.java public class CarCounterTest { public static void main( String args[] ){ VehicleCounter vehicle1 = new VehicleCounter(); VehicleCounter vehicle2 = new CarCounter(); System.out.println(VehicleCounter.getCounter()); System.out.println(CarCounter .getCounter()); } }

Hope this explains.

NawaMan :-D

Comments

0

Static members should be accessed statically, i.e., ClassName.memberName. Non-static access is allowed though (objectName.memberName) but is discouraged.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.