Connecting Tech Pros Worldwide Forums | Help | Site Map

Declaring Methods and classes final

momotaro's Avatar
Needs Regular Fix
 
Join Date: Sep 2006
Posts: 259
#1: Jun 12 '08
can some one explain to me what are the adventages of such use?
I tried to understand what sun is posting on the tutorial but they don't explain that much

Plz help!

JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#2: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by momotaro

can some one explain to me what are the adventages of such use?
I tried to understand what sun is posting on the tutorial but they don't explain that much

Plz help!

Suppose I've made a class and I don't want anyone to override a method in an
extending class; I can make that method final. Suppose I don't want anyone to
extend their class from my class; I can make that entire class final.

kind regards,

Jos
momotaro's Avatar
Needs Regular Fix
 
Join Date: Sep 2006
Posts: 259
#3: Jun 12 '08

re: Declaring Methods and classes final


in the java tutorial site they stated:
"Methods called from constructors should generally be declared final. If a constructor calls a non-final method, a subclass may redefine that method with surprising or undesirable results."
why methods called from constractors??
BigDaddyLH's Avatar
Moderator
 
Join Date: Dec 2007
Location: Kelowna, BC Canada
Posts: 1,212
#4: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by momotaro

why methods called from constractors??

Expand|Select|Wrap|Line Numbers
  1. public class Example {
  2.     private String text;
  3.  
  4.     public final String getText() {
  5.         return text;
  6.     }
  7.  
  8.     public final void setText(String text) {
  9.         this.text = (text == null) ? "" : text.trim();
  10.     }
  11.  
  12.     public Example() {
  13.     }
  14.  
  15.     public Example(String text) {
  16.         setText(text);
  17.     }
  18. }
BigDaddyLH's Avatar
Moderator
 
Join Date: Dec 2007
Location: Kelowna, BC Canada
Posts: 1,212
#5: Jun 12 '08

re: Declaring Methods and classes final


And here's an example of where logic may go awry when a polymorphic method is called from a constructor.

Expand|Select|Wrap|Line Numbers
  1. class Example {
  2.     protected String text;
  3.  
  4.     public String getText() {
  5.         return text;
  6.     }
  7.  
  8.     public void setText(String text) {
  9.         this.text = (text == null) ? "" : text.trim();
  10.     }
  11.  
  12.     public Example() {
  13.     }
  14.  
  15.     public Example(String text) {
  16.         setText(text);
  17.     }
  18. }
  19.  
  20. public class SubExample extends Example {
  21.     private boolean preserveNull;
  22.  
  23.     public SubExample(String text, boolean preserveNull) {
  24.         super(text);
  25.         this.preserveNull = preserveNull;
  26.     }
  27.  
  28.     @Override()
  29.     public void setText(String text) {
  30.         System.err.println("in setText, preserveNull is " + preserveNull);
  31.         if (preserveNull) {
  32.             this.text = (text == null) ? null : text.trim();
  33.         } else {
  34.             super.setText(text);
  35.         }
  36.     }
  37.  
  38.     public static void main(String[] args) {
  39.         Example app = new SubExample(null, false);
  40.         System.out.format("text=(%s)%n", app.getText()); //blank -- as expected
  41.  
  42.         Example app2 = new SubExample(null, true);
  43.         System.out.format("text=(%s)%n", app2.getText());//blank -- why not null?
  44.     }
  45.  
  46. }
momotaro's Avatar
Needs Regular Fix
 
Join Date: Sep 2006
Posts: 259
#6: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by BigDaddyLH

Expand|Select|Wrap|Line Numbers
  1. public class Example {
  2.     private String text;
  3.  
  4.     public final String getText() {
  5.         return text;
  6.     }
  7.  
  8.     public final void setText(String text) {
  9.         this.text = (text == null) ? "" : text.trim();
  10.     }
  11.  
  12.     public Example() {
  13.     }
  14.  
  15.     public Example(String text) {
  16.         setText(text);
  17.     }
  18. }

Sorry but can you explain me your code?
this is my first week of java.
BigDaddyLH's Avatar
Moderator
 
Join Date: Dec 2007
Location: Kelowna, BC Canada
Posts: 1,212
#7: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by momotaro

Sorry but can you explain me your code?
this is my first week of java.

What don't you understand?
momotaro's Avatar
Needs Regular Fix
 
Join Date: Sep 2006
Posts: 259
#8: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by BigDaddyLH

What don't you understand?

the purpose of that code
BigDaddyLH's Avatar
Moderator
 
Join Date: Dec 2007
Location: Kelowna, BC Canada
Posts: 1,212
#9: Jun 12 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by momotaro

the purpose of that code

It demonstrates why one might want to call a method from a constructor.
Expert
 
Join Date: Nov 2007
Location: Germany
Posts: 294
#10: Jun 13 '08

re: Declaring Methods and classes final


Please correct me if I am wrong, but this example demonstrates the use of a not-initialized variable instead of an awry logic or the question why a method called from a constructor should be final.
The question is why app2.getText() returns blank instead of null, and I think following happens:

By calling SubExample(null, true), the method-scope variable preserveNull is set to true, but the class variable preserveNull is still "undefined". That means by just declaring it with private boolean preserveNull; its value will be initialized to "false" automatically by java, that means it's the same as writing private boolean preserveNull = false;.
If super(text) is executed next, then setText(text) is executed in Example(String text) which executes the method setText() in Example and not in SubExample. (Correct me if I am wrong here). Then the statement if (preserveNull) is evaluated and here it always jumps into the else-clause because preserveNull is "undefined", that means false. Setting preserveNull afterwards when it returns from the super(text); therefore has no effect.

I have not yet tried to run the code example, but if you would put super(text); before this.preserveNull = preserveNull; everything would run as expected and not awry. Wait, is this allowed? I remember that super() must be the first command executed in a constructor, so exchanging the statements would not work. Hmmm...
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#11: Jun 13 '08

re: Declaring Methods and classes final


An object is constructed as an onion layer: first the inner layers must be there,
i.e. first the superclass object must be constructed before the outer layer (the
sub class object) can be set up and initialized. When you jump from an inner
layer to an outer layer during construction time of the inner layer itself you can
be sure that the outer layer hasn't been initialized yet.

Jumping from an inner layer to an outer layer during construction time happens
when the superclass constructor calls a method that is overridden by one in
that (not yet existing) outer layer (i.e. derived class). That's why it is advisable
to make those methods that are called by a constructor as private so that they
can't be overridden and so that you can't 'jump' to an outer layer.

kind regards,

Jos
momotaro's Avatar
Needs Regular Fix
 
Join Date: Sep 2006
Posts: 259
#12: Jun 13 '08

re: Declaring Methods and classes final


josAH !! you rock!!!

this is the explanation that I was waiting for !!!
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#13: Jun 13 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by momotaro

josAH !! you rock!!!

this is the explanation that I was waiting for !!!

You're welcome of course; if you like the union layer analogy keep it in mind
when you design and implement your classes.

kind regards,

Jos
BigDaddyLH's Avatar
Moderator
 
Join Date: Dec 2007
Location: Kelowna, BC Canada
Posts: 1,212
#14: Jun 13 '08

re: Declaring Methods and classes final


Quote:

Originally Posted by chaarmann

Please correct me if I am wrong, but this example demonstrates the use of a not-initialized variable instead of an awry logic or the question why a method called from a constructor should be final.
The question is why app2.getText() returns blank instead of null, and I think following happens:

By calling SubExample(null, true), the method-scope variable preserveNull is set to true, but the class variable preserveNull is still "undefined". That means by just declaring it with private boolean preserveNull; its value will be initialized to "false" automatically by java, that means it's the same as writing private boolean preserveNull = false;.
If super(text) is executed next, then setText(text) is executed in Example(String text) which executes the method setText() in Example and not in SubExample. (Correct me if I am wrong here). Then the statement if (preserveNull) is evaluated and here it always jumps into the else-clause because preserveNull is "undefined", that means false. Setting preserveNull afterwards when it returns from the super(text); therefore has no effect.

I have not yet tried to run the code example, but if you would put super(text); before this.preserveNull = preserveNull; everything would run as expected and not awry. Wait, is this allowed? I remember that super() must be the first command executed in a constructor, so exchanging the statements would not work. Hmmm...

The OP actually asked for an explanation of the first, simpler, example.

And to "fix" the second example, I would do the following.

Expand|Select|Wrap|Line Numbers
  1. public SubExample(String text, boolean preserveNull) {
  2.     super();
  3.     this.preserveNull = preserveNull;
  4.     setText(text);
  5. }
Reply