2

In the following example, the variable b is declared final, but not static. That means it's a constant instance variable. However, because it's constant, none of the Passenger objects can change its value. So isn't it better to declare it static and make it a class variable, so that there is only one copy to be used by all instantiated objects?

class Passenger {
    int a;
    final int b = 0;

    void drive() {
        System.out.println("I'm driving!");
    }
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Nitin Garg
  • 177
  • 2
  • 3
  • 10

6 Answers6

10

The purpose of final but non-static variables is to have an object-wide constant. It should be initialized in the constructor:

class Passenger {
    final int b;

    Passenger(int b) {
        this.b = b;
    }
}

If you are always assigning a constant literal value (0) to the final variable, it doesn't make much sense. Using static is preferred so that you are only having a single copy of b:

static final int b = 0;

BTW I don't think having default access modifier was your intention.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
1

It depends on the purpose of b. Usually constants are there for a specific purpose. If you make it static you could accidentally change it in some instance of that class and that will affect all the others.

Bogdan Emil Mariesan
  • 5,529
  • 2
  • 33
  • 57
1

If you have multiple instances of Passenger class, I would go for making it static. While this has little benefit when talking about an int variable, this could save some memory if you have complex objects. This is because a static variable belongs to a class, not to an instance, thus memory space for it will be reserved only once, and it will be referred by the class object itself, not by the instances. Of course, you should be aware that having b as a static variable means that the changes made on this variable will be reflected on all the classes that access this variable, but since you made it final this won't be the case.

Note also that with the code you've written, classes in the same package as Passenger will be able to read the b value by accessing it via Passenger.b (if static).

manub
  • 3,990
  • 2
  • 24
  • 33
  • Yes, saving memory for large variables was exactly my reason for declaring it static. I omitted the access modifiers in this example. I suspected a lot of people will notice that :D – Nitin Garg Mar 14 '12 at 10:06
  • 1
    Of course, if you have complex object, remember that only the reference will be final, but unless you make them immutable you can still change the internal state by operating on methods, if any are exposed. And this way, since the object is shared between all the instances, changes in the internal state will be reflected on all the readers of that object. – manub Mar 14 '12 at 10:08
  • Oh, I see what you mean. http://stackoverflow.com/questions/1249917/final-variable-manipulation-in-java – Nitin Garg Mar 14 '12 at 10:15
0

A final variable is defined when you need a constant, so you can assign a value just once. Using static, instead, you are defining a variable shared by all the objects of that type (like a global variable) and it is not associated with a certain object itself.

Verdi
  • 84
  • 2
  • 10
0

In java, the static attribute basically means: associated with the type itself, rather than an instance of the type.

In other words you can reference a static variable without creating instances of that type... Whereas in the case of just using final you'd need to instantiate the class.

So, yes, to answer your question, I'd say that you're right. :)

Andreas Johansson
  • 1,135
  • 6
  • 23
0

A final primitive is the same as a static final primitive (except more efficient)

A final reference to an immutable object the same as a static final reference of the same.

A final reference to a mutable object is NOT the same as a static final reference of the same.

final int i = 0;
// same as
static final int = 0;

final String hi = "Hello";
// same as
static final String hi = "Hello";

final List<String> list = new ArrayList<String>();
// is NOT the same as
static final List<String> list = new ArrayList<String>();

The only time the last example is the same is when you have a singleton. It is fairly common for singletons to be written with a confusion of static and non static fields and methods as the difference is not obvious. :|

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130