Hello
I have been wondering why the final keyword for instance variables is
not more flexible.
Often in my code I find situation when it would have been
helpful/produced nicer code if I were able to change a final variable
while being in the constructor .
Is there any reason behind it that we can't change a final variable
multiple times while we are in the constructor?
It would be interesting to know why it is like it is in java.
What benefit does java get by not allowing this?
Christian
Stefan Ram - 28 Oct 2007 19:41 GMT
>Often in my code I find situation when it would have been
>helpful/produced nicer code if I were able to change a final
>variable while being in the constructor .
If this happens so often, then it
should be easy to post an example.
Christian - 28 Oct 2007 20:09 GMT
Stefan Ram schrieb:
>> Often in my code I find situation when it would have been
>> helpful/produced nicer code if I were able to change a final
>> variable while being in the constructor .
>
> If this happens so often, then it
> should be easy to post an example.
here an example for my last recent occurence..
/**
* decorates a normal NC Block that is a TreeCoding Block
*/
public TreeCodingBlock(INCBlock block, TreeCodingBlockmanager manager) {
this.decorated = block;
this.manager = manager;
int firstPositionUnequalZero = 0;
int lastPositionUnequalZero = 0 ;
ByteVector linearfactors = block.getLinearFactors();
for (int i=0; i < linearfactors.length(); i++) {
if (linearfactors.getElement(i) != 0) {
firstPositionUnequalZero = i;
break;
}
}
for (int i = linearfactors.length()-1 ; i >= 0 ; i-- ) {
if (linearfactors.getElement(i) != 0) {
lastPositionUnequalZero = i;
break;
}
}
this.firstPositionUnequalZero = firstPositionUnequalZero;
this.lastPositionUnequalZero = lastPositionUnequalZero;
}
Well I can remember worse examples.. here it adds just four lines of
code. Though four lines that seem unecessary.
Stefan Ram - 28 Oct 2007 20:27 GMT
>for (int i=0; i < linearfactors.length(); i++) {
> if (linearfactors.getElement(i) != 0) {
> firstPositionUnequalZero = i;
This breaks Demeter's Law, because it addresses an object
»linearfactors« obtained from a parameter object (»block«).
It also breaks the GRASP information expert pattern: »block«
has the information to calculate »firstPositionUnequalZero«,
so it should implement this operation.
Thus (simplified):
public TreeCodingBlock
( final INCBlock block )
{ this.firstPositionUnequalZero = block.firstPositionUnequalZero();
this.lastPositionUnequalZero = block.lastPositionUnequalZero(); }
Christian - 28 Oct 2007 21:07 GMT
Stefan Ram schrieb:
>> for (int i=0; i < linearfactors.length(); i++) {
>> if (linearfactors.getElement(i) != 0) {
[quoted text clipped - 13 lines]
> { this.firstPositionUnequalZero = block.firstPositionUnequalZero();
> this.lastPositionUnequalZero = block.lastPositionUnequalZero(); }
for INCBlock interface the first position unequal to zero has no meaning...
therefore it was not implemented in INCBlock , also ByteVector had no
need for such a method
TreeCodingBlock is in a plug-in that provides a "Blockmanager" a class
that may decorate any INCBlocks .. this decorater now has some use to
have a fast way to know whats the first factor unequal to zero is ..
though I will follow Daniel Pits advice and add it to the ByteVector's
methods as it is not really a problem to change to original program..
thx
Daniel Pitts - 28 Oct 2007 20:33 GMT
> Stefan Ram schrieb:
>>> Often in my code I find situation when it would have been
[quoted text clipped - 33 lines]
> Well I can remember worse examples.. here it adds just four lines of
> code. Though four lines that seem unecessary.
Try refactoring to replace temp with query:
private static int findFirstNonZeroPosition(ByteVector bv);
private static int findLastNonZeroPosition(ByteVector bv);
Actually, better yet, add those methods as instance methods to
ByteVector if possible.

Signature
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
Eric Sosman - 28 Oct 2007 20:21 GMT
> Hello
>
[quoted text clipped - 6 lines]
> Is there any reason behind it that we can't change a final variable
> multiple times while we are in the constructor?
The only scenario I can think of where a `semifinal' might
help is when there are multiple constructors, and one of them
chains to another before setting the variable:
private Something instanceVariable;
public SomeClass() {
doLotsOfStuff();
instanceVariable = new Something(42);
}
public SomeClass(int value) {
this();
instanceVariable = new Something(value);
}
The obvious answer in this case is to rearrange responsibilities:
private Something instanceVariable;
public SomeClass() {
this(42);
}
public SomeClass(int value) {
doLotsOfStuff();
instanceVariable = new Something(value);
}
Or perhaps you're worried about running a loop that might
set the variable several times, as in:
private Something instanceVariable();
public SomeClass(Collection<Something> things) {
for (Something thing : things)
if (thing.somePredicate())
instanceVariable = thing;
}
This is easily fixed by introducing a local variable:
private Something instanceVariable;
public SomeClass(Collection<Something> things) {
Something chosen = null;
for (Something thing : things)
if (thing.somePredicate())
chosen = thing;
instanceVariable = chosen;
}
If you have some other situation that seems to cry out for
a `semifinal' variable, please post it.
> It would be interesting to know why it is like it is in java.
> What benefit does java get by not allowing this?
Simplicity: If the rules are easy to state ("one and only
one assignment") things are easier for both the compiler and
for the human reader. Error detection: Did the programmer truly
intend to make multiple assignments, or did some execution path
escape his notice? Maybe other reasons, too.
Let's turn the question around: What benefit would accrue
from *allowing* `semifinal' variables?

Signature
Eric Sosman
esosman@ieee-dot-org.invalid
Roedy Green - 28 Oct 2007 22:51 GMT
>Is there any reason behind it that we can't change a final variable
>multiple times while we are in the constructor?
because final means FINAL, not to be changed again. If you need to do
some temporary calculation before coming up with the value, put the
temps is a local variables, then mark the result final.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com