Declaring Methods and classes final

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • momotaro
    Contributor
    • Sep 2006
    • 357

    Declaring Methods and classes final

    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
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    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

    Comment

    • momotaro
      Contributor
      • Sep 2006
      • 357

      #3
      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??

      Comment

      • BigDaddyLH
        Recognized Expert Top Contributor
        • Dec 2007
        • 1216

        #4
        Originally posted by momotaro
        why methods called from constractors??
        [CODE=Java]public class Example {
        private String text;

        public final String getText() {
        return text;
        }

        public final void setText(String text) {
        this.text = (text == null) ? "" : text.trim();
        }

        public Example() {
        }

        public Example(String text) {
        setText(text);
        }
        }[/CODE]

        Comment

        • BigDaddyLH
          Recognized Expert Top Contributor
          • Dec 2007
          • 1216

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

          [CODE=Java]class Example {
          protected String text;

          public String getText() {
          return text;
          }

          public void setText(String text) {
          this.text = (text == null) ? "" : text.trim();
          }

          public Example() {
          }

          public Example(String text) {
          setText(text);
          }
          }

          public class SubExample extends Example {
          private boolean preserveNull;

          public SubExample(Stri ng text, boolean preserveNull) {
          super(text);
          this.preserveNu ll = preserveNull;
          }

          @Override()
          public void setText(String text) {
          System.err.prin tln("in setText, preserveNull is " + preserveNull);
          if (preserveNull) {
          this.text = (text == null) ? null : text.trim();
          } else {
          super.setText(t ext);
          }
          }

          public static void main(String[] args) {
          Example app = new SubExample(null , false);
          System.out.form at("text=(%s)%n ", app.getText()); //blank -- as expected

          Example app2 = new SubExample(null , true);
          System.out.form at("text=(%s)%n ", app2.getText()) ;//blank -- why not null?
          }

          }[/CODE]

          Comment

          • momotaro
            Contributor
            • Sep 2006
            • 357

            #6
            Originally posted by BigDaddyLH
            [CODE=Java]public class Example {
            private String text;

            public final String getText() {
            return text;
            }

            public final void setText(String text) {
            this.text = (text == null) ? "" : text.trim();
            }

            public Example() {
            }

            public Example(String text) {
            setText(text);
            }
            }[/CODE]
            Sorry but can you explain me your code?
            this is my first week of java.

            Comment

            • BigDaddyLH
              Recognized Expert Top Contributor
              • Dec 2007
              • 1216

              #7
              Originally posted by momotaro
              Sorry but can you explain me your code?
              this is my first week of java.
              What don't you understand?

              Comment

              • momotaro
                Contributor
                • Sep 2006
                • 357

                #8
                Originally posted by BigDaddyLH
                What don't you understand?
                the purpose of that code

                Comment

                • BigDaddyLH
                  Recognized Expert Top Contributor
                  • Dec 2007
                  • 1216

                  #9
                  Originally posted by momotaro
                  the purpose of that code
                  It demonstrates why one might want to call a method from a constructor.

                  Comment

                  • chaarmann
                    Recognized Expert Contributor
                    • Nov 2007
                    • 785

                    #10
                    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.preserveNu ll = 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...

                    Comment

                    • JosAH
                      Recognized Expert MVP
                      • Mar 2007
                      • 11453

                      #11
                      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

                      Comment

                      • momotaro
                        Contributor
                        • Sep 2006
                        • 357

                        #12
                        josAH !! you rock!!!

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

                        Comment

                        • JosAH
                          Recognized Expert MVP
                          • Mar 2007
                          • 11453

                          #13
                          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

                          Comment

                          • BigDaddyLH
                            Recognized Expert Top Contributor
                            • Dec 2007
                            • 1216

                            #14
                            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.preserveNu ll = 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.

                            [CODE=Java]public SubExample(Stri ng text, boolean preserveNull) {
                            super();
                            this.preserveNu ll = preserveNull;
                            setText(text);
                            }[/CODE]

                            Comment

                            Working...