Why must and must not be "final" ?

N

NeoGeoSNK

"Thomas Hawtin дµÀ£º
"
Andreas said:
An extra note:
This doesn't mean that you couldn't share non-final
references between the outer and inner class! Just
wrap it up into some container-class.

Simple example:

class Outer {
final TextField[] tf = new TextField[1];
class Inner
{
// use and modify tf[0] at will.
}
void init()
{
// use and modify tf[0] at will.
}
}

I'm not sure how useful an example that is. IIRC, it does mean (from
1.5) that you can guarantee that tf[0] is non-null, even with unsafe
publishing. For local classes you can do much the same (but use
AtomicReference):

String foo(String arg) {
final AtomicReference<String> argRef =
new AtomicReference<String>(arg);

new Object() {
void bar() {
argRef.set('<'+argRef.get()+'>');
}
}.bar();

return argRef.get();
}

But please don't. :)

Tom Hawtin

Thanks Tom Hawtin
And I think AtomicReference is more complex than Inner class:)
 
N

NeoGeoSNK

"Mark Rafn дµÀ£º
"
There is a distinction between member variables, local variables, and
formal parameter variables (though the last two are darned similar).

There is also a distinction between anonymous inner classes, named
inner classes, and static inner classes.

An anonymous inner class is defined inside a method, and has access to all
member variables of the enclosing class, final or not (which isn't your
question), and to all final variables and parameters of the method in which
it's declared (which is what you're asking about). The reason they have
to be final is because they're locally scoped and will disappear as
soon as the method returns, which would be very bad for the anonymous class
that tries to reference them later. The final modifier means it's safe for
the anonymous class to keep a copy of the value when it's created, as it's
guranteed not to change.

Named inner classes (those that are members of a class, not declared inside a
method) have no access to any method's parameters or variables at all, so
nothing needs to be declared final. It has access to member variables of the
enclosing class through an implicit OuterClassName.this reference.

Named static inner classes are exactly like top-level classes (which are
implicitly static). They have no access to any outside variables, except
through an explicit reference just like any other class would.


This is unrelated to your first question. Final member variables must be
assigned at class construction time (through an initializer in the
declaration, an initializer block, or inside a constructor. Any attempt to
assign to a final member after this is illegal. That's what final means - it
can't be assigned after construction.







Thanks Mark Rafn
your explain is very clear, before i see your comment, I searched many
java books and couldn't find the answer^ ^.I think I can understand
when I should declare a final variables or not from your answer, But I
still don't don't know why
the compiler must guranteed it not to change? why it is /safe/ :)
 
N

NeoGeoSNK

"Andreas Leitgeb дµÀ£º
"
Mark Rafn said:
Andreas Leitgeb said:
class Outer {
final TextField[] tf = new TextField[1];
...
}
This isn't necessary for member variables. Just make them non-final and all
is well. It's an ugly but effective workaround when an anonymous inner class
needs access to local variables or parameters that you want to change.

trapped.
I mixed up the context while writing the followup.

I meant:
void myFunc() {
final TextField[] tf = new TextField[1];
new Object() { void foo() { tf[0]=<whatever>; } }.foo();
// now tf[0] is <whatever>.
}

AtomicReference appears to me like overkill in this respect,
since we're talking about local variables, that are "rarely"
(that is: never ever) shared among threads...

Thanks Andreas Leitgeb
And does that means a final array's elements can be modified any times?
and it's unrelated with inner class?
 
A

Andreas Leitgeb

NeoGeoSNK said:
And does that means a final array's elements can be modified any times?
yes

and it's unrelated with inner class?

1.) Here we're talking about inner classes in the context that they
are defined inside a method.

2.) The inner class really gets a copy of all enclosing
method's variables that it wants to access.

3.) because the inner class gets only a copy of them, it cannot
modify the enclosing method's local variables (the originals).

4.) to prevent people from modifying the copies and then
complaining that the originals remained unchanged, the
originals are forced to be final, preventing any discussion
about any connectivity between copy & original. If it's
final, then it's trivially "connected" to the copy.

5.) It surely could have been done hundred other ways, but it
wasn't :)

That's why a local variable must be final, IF you want to access
it from an inner class.
 
N

NeoGeoSNK

"Andreas Leitgeb дµÀ£º
"
1.) Here we're talking about inner classes in the context that they
are defined inside a method.

2.) The inner class really gets a copy of all enclosing
method's variables that it wants to access.

3.) because the inner class gets only a copy of them, it cannot
modify the enclosing method's local variables (the originals).

4.) to prevent people from modifying the copies and then
complaining that the originals remained unchanged, the
originals are forced to be final, preventing any discussion
about any connectivity between copy & original. If it's
final, then it's trivially "connected" to the copy.

5.) It surely could have been done hundred other ways, but it
wasn't :)

That's why a local variable must be final, IF you want to access
it from an inner class.


Thanks very much Andreas Leitgeb
I Think I completely understand :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top