Reputation: 2114
I was looking at another question about final variables and noticed that you can declare final variables without initializing them (a blank final variable). Is there a reason it is desirable to do this, and when is it advantageous?
Upvotes: 14
Views: 14572
Reputation: 2154
I find them very useful for methods that derive a state. It provides a clean execution path and makes sure the state variable is assigned once and only once. For example:
public boolean isEdible() {
final boolean edible;
if (vegetable) {
edible = true;
} else if (animal) {
if (vegetarian) {
edible = false;
} else {
edible = true;
}
}
System.out.println("Is edible: " + edible);
return edible;
}
Upvotes: 0
Reputation: 4443
You can do this when you do not known what the value will be prior to the instrumentation of a Object, it just needs to have a value assigned in its constructor.
This is how you make immutable objects and it is used in the builder pattern.
class Builder{
final BuilderContext context;
private Builder(BuilderContext context){
this.context=context;
}
public static Builder New(){
return new Builder(new BuilderContext());
}
Upvotes: 2
Reputation: 11
Use a blank final variable inside a method to show that all code paths which use the variable assign that variable exactly once (or throw an exception). Java compilers will guarantee that a blank final variable is assigned before it is used.
Example code inside some method:
final Foo foo;
if (condition1()) {
foo = makeFoo(1);
} else if (condition2()) {
throw new BarException();
} else {
foo = makeFoo(-1);
}
...
blahBlahBlah(foo);
Using blank final variables tells the next reader of the code that the compiler guarantees that someone assigned foo before calling blahBlahBlah(foo).
The question asks about "blank final variables". Discussion of "blank final fields" is a different discussion, and interesting in its own right.
Upvotes: 1
Reputation: 5086
One case could be when you have a field which you want to declare final, but whose assignment may throw an exception and you want to be able to take action if that happens:
class A {
final URLConnection conn;
A(String url) {
try {
this.conn = new URL(url).openConnection();
} catch (IOException | MalformedURLException e) {
// Maybe this isn't fatal, so just handle the Exception
// here and move on happily
}
}
}
Upvotes: 1
Reputation: 328598
This is useful to create immutable objects:
public class Bla {
private final Color color;
public Bla(Color c) {this.color = c};
}
Bla is immutable (once created, it can't change because color is final). But you can still create various Blas by constructing them with various colors.
See also this question for example.
EDIT
Maybe worth adding that a "blank final" has a very specific meaning in Java, which seems to have created some confusion in the comments - cf the Java Language Specification 4.12.4:
A blank final is a final variable whose declaration lacks an initializer.
You then must assign that blank final variable in a constructor.
Upvotes: 30
Reputation: 30865
The final property of class must have a value assigned before object is created. So the last point where you can assign value to them is constructor.
This is used often for immutable objects.
public class Foo {
private final Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
public Bar getBar() {
return new Bar(bar);
}
}
Upvotes: 5
Reputation: 124215
noticed that you can declare
final
variables without initializing them
You have to initialize it later (for example in the constructor) so it wont stay empty.
Upvotes: 0
Reputation: 4745
Blank final variables must be assigned "somewhere" in the constructor. A rather constructed example:
public class Test {
final int sign;
public Test(String upDown) {
if (upDown.equals("up")) {
sign = +1;
} else {
sign = -1;
}
}
}
Upvotes: 1
Reputation: 744
From Wikipedia
The blank final, which was introduced in Java 1.1, is a final variable whose declaration lacks an initializer. A blank final can only be assigned once and must be unassigned when an assignment occurs. In order to do this, a Java compiler runs a flow analysis to ensure that, for every assignment to a blank final variable, the variable is definitely unassigned before the assignment; otherwise a compile-time error occurs.
In general, a Java compiler will ensure that the blank final is not used until it is assigned a value and that once assigned a value, the now final variable cannot be reassigned another value.
Upvotes: 0