why is var superValue not getting initialized to 911 in this code

Discussion in 'Java' started by ankur, Nov 23, 2008.

  1. ankur

    ankur Guest

    I was little confused as to how the this reference works in this case.
    I thought that the this reference in SuperClassA constructor would
    call the doValue() in superclass A.

    package pack4;
    class SuperclassA {
    protected int superValue; // (1)
    SuperclassA() { // (2)
    System.out.println("Constructor in SuperclassA");
    this.doValue(); // (3)
    void doValue() { // (4)
    this.superValue = 911;
    System.out.println("superValue: " + this.superValue);

    class SubclassB extends SuperclassA {
    private int value = 800; // (5)
    SubclassB() { // (6)
    System.out.println("Constructor in SubclassB");
    System.out.println("superValue: " + this.superValue);
    void doValue() { // (7)
    System.out.println("value: " + this.value);

    public class ObjectInitialization {
    public static void main(String[] args) {
    System.out.println("Creating an object of SubclassB.");
    new SubclassB(); // (8)

    Output :

    Creating an object of SubclassB.
    Constructor in SuperclassA
    value: 0
    Constructor in SubclassB
    value: 800
    superValue: 0

    ankur, Nov 23, 2008
    1. Advertisements

  2. ankur

    Arne Vajhøj Guest

    All methods are virtual in Java.

    But calling a method like this in a constructor is a big no no.

    Arne Vajhøj, Nov 23, 2008
    1. Advertisements

  3. ankur

    Mark Space Guest

    Mark Space, Nov 23, 2008
  4. ankur

    Mark Space Guest

    (Sorry about the previous post, pilot error.)

    "this" refers to the object, not the class. Since doValue() is
    overloaded by SubclassB, when you create that object, it is SubclassB's
    doValue() that gets called.

    As Arne said, calling a method that can be overloaded from a constructor
    is a very bad idea. It will get you all sorts of trouble.

    Two suggestions: 1. Make doValue "final". Then it cannot be overloaded
    by SubclassB, although SubclassB's doValue method will be illegal. 2.
    Make doValue "private". Then it still cannot be overloaded by
    SubclassB, although it can't be seen by any classes either.
    Mark Space, Nov 23, 2008
  5. Nope. All method calls (except calls to private methods or calls via
    |super|) are virtual method calls. The value of |this| does not change
    between super/subclasses. It doesn't matter if you're in a constructor
    or somewhere else.

    Note that for this reason, and the additional requirements on order of
    class initialization, it is extremely, extremely bad to call any
    non-private or non-final method in a constructor of a non-final class.
    It is indeed bad to let |this| escape a constructor in any circumstance
    except under certain, carefully controlled circumstances
    (java.util.Random is a notable class that fails this requirement badly).
    Joshua Cranmer, Nov 23, 2008
  6. ankur

    Lew Guest

    overridden by
    Lew, Nov 23, 2008
  7. ankur

    Lew Guest

    If the subclass were in a different package, then there would not be an
    override in the example because 'doValue()' has package-private access there.
    Lew, Nov 23, 2008
  8. ankur

    Mark Space Guest

    Yup on both counts. That's what I get for posting when I'm rushing off
    to lunch.
    Mark Space, Nov 23, 2008
  9. ankur

    ankur Guest

    Lew, you are right ..again ! So what would 'doValue()' of SubclassB be
    doing in this case ? Whats the technical term for that, because it is
    definitely not overriding ( and neither overloading, hiding ,
    shadowing or obscuring) ?
    ankur, Nov 24, 2008
  10. ankur

    Lew Guest

    (citation restored)
    None of the above. It's just a new method.
    Lew, Nov 24, 2008
  11. ankur

    ankur Guest

    hmmm , i c. wow. Lets coin a term, write to sun and get it included in
    the JLS !
    ankur, Nov 24, 2008
  12. ankur

    Lew Guest

    That doesn't seem necessary. The superclass package-private method is
    invisible to a subclass method from a different package, so from the subclass
    point of view it doesn't exist, in that respect being just like a private

    What do you call hiding something that doesn't exist?
    Lew, Nov 24, 2008
  13. ankur

    ankur Guest

    In this particular scenario when I declare a method in the subclass
    with the same signature in the superclass, java gives me warning that"
    the method does not override the inherited method from superclass
    etc...". Moreover the method cannot be used if declared this way to
    exhibit polymorphic behavior. All I am saying is that there needs to
    be a term to describe this kind of behavior ( or rather a pitfall on
    part of programmer).
    ankur, Nov 24, 2008
  14. ankur

    Lew Guest

    Huh? I get no such warning.

    Are you certain that this is a warning when you declare a package-private
    method in the subclass that matches the signature of a parent-class
    package-private method, where child and parent are in different packages?

    Please post a *complete* example and the *exact*, *complete* compiler message.

    <example class="testit.Parent">
    package testit;

    /** Parent. */
    public class Parent
    /* p-p */ void packard()
    System.out.println( "Super.packard()" );

    <example class="testit.other.OtherOffspring">
    package testit.other;

    import testit.Parent;

    /** OtherOffspring. */
    public class OtherOffspring extends Parent
    /* p-p */ void packard()
    System.out.println( "Offspring.packard()" );

    Compiles without warning or error for me.
    I disagree. If a method is invisible to the child class, then there is no
    method to override or hide. About the only term that makes sense is that the
    child class has a "non-overriding method", hardly distinguishing as it is the
    normal case that methods do not override.

    What would you call such a method, that does not hide, override, overload or
    otherwise interact with a parent-class method, other than simply "a method"?
    Lew, Nov 24, 2008
  15. ankur

    J. Davidson Guest

    Compiler should give a warning for that if you ask me.

    - jenny
    J. Davidson, Nov 24, 2008
  16. ankur

    ankur Guest

    I use eclipse and here's what I observed.
    I moved SuperclassA and ObjectInitialization in same package and
    moved SubclassB to a new package. I kept the package accessibility for
    doValue() in both super class and sub class. I for a warning right
    next to the doValue in SubclassB that "the method does not override
    the inherited method from superclass etc...". Its the exact same code
    that I posted earlier but I just moved the classes to new packages. Of
    course I had to make SubclassB and SuperclassA public as I used
    separate .java files for them.
    ankur, Nov 24, 2008
  17. ankur

    Arne Vajhøj Guest

    I would not complain.

    Arne Vajhøj, Nov 25, 2008
  18. ankur

    Lew Guest

    That really does not look like an exact quote of the warning. Did it really
    say "etc...." like that, with no preceding comma and four periods?

    Are you also saying that this was an Eclipse warning, not a Java warning?
    That would explain why I got no warning whatsoever from javac when I compiled
    my example.

    Interesting that Eclipse would give a warning for perfectly valid Java code.
    I don't think it makes much sense for the Java language to change itself to
    accommodate an IDE-specific feature.
    Lew, Nov 25, 2008
  19. ankur

    Lew Guest

    Three! Three periods. Sorry.
    Lew, Nov 25, 2008
  20. If it was not valid, then it would be an error not a warning.

    The distinction between Eclipse and compiler is a bit fuzzy
    since Eclipse uses its own compiler.

    Arne Vajhøj, Nov 25, 2008
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.