inner class loses track of int[] variable

Discussion in 'Java' started by Composer, Feb 23, 2009.

  1. Composer

    Composer Guest

    My class has an inner class as follows (irrelevant parts omitted):

    class ResultInstance
    { private int[] s;

    // Constructor method
    public ResultInstance(int[] series)
    { s = series;
    System.out.println(PitchClassSet.toString(s)); // At
    this point it's fine !!!
    }

    protected int[] getSeries()
    { System.out.println(PitchClassSet.toString(s)); // By now
    it's been screwed up !!!
    return s;
    }
    }

    At the point where the main class creates a new ResultInstance, I can
    verify that the array "s" is fine.
    All the ResultInstances are put into a Vector. Later I pull them out
    using an Enumeration.
    At that point, some of the "s" arrays have been replaced with those
    that belong to later ResultInstances.

    No doubt I'm doing something stupid. Can someone help me spot it?
    Thanks.
     
    Composer, Feb 23, 2009
    #1
    1. Advertising

  2. Composer

    Lew Guest

    Composer wrote:
    > My class has an inner class as follows (irrelevant parts omitted):


    You've also omitted some very relevant parts, like the definition of
    'PitchClassSet'. You also omitted what's being done to the array to which 's'
    points.

    > class ResultInstance


    Your gaps are far too wide for Usenet readability.

    > { private int[] s;
    >
    > // Constructor method
    > public ResultInstance(int[] series)
    > { s = series;
    > System.out.println(PitchClassSet.toString(s)); // At
    > this point it's fine !!!
    > }
    >
    > protected int[] getSeries()
    > { System.out.println(PitchClassSet.toString(s)); // By now
    > it's been screwed up !!!
    > return s;
    > }
    > }
    >
    > At the point where the main class creates a new ResultInstance, I can
    > verify that the array "s" is fine.


    How is the input 'series' used by the class that uses 'ResultInstance'?

    > All the ResultInstances are put into a Vector. Later I pull them out
    > using an Enumeration.
    > At that point, some of the "s" arrays have been replaced with those
    > that belong to later ResultInstances.
    >
    > No doubt I'm doing something stupid. Can someone help me spot it?


    First thing you shouldn't be doing, though it's not the reason for the problem
    you see, is using 'Vector' or 'Enumeration'. Those classes were replaced in
    1998, for Pete's sake! Use 'ArrayList' and 'Iterator'.

    The problem you're seeing is that all 'ResultInstance' instances are using the
    same array. Every 'ResultInstance' instance's 's' is pointing to the same array.

    --
    Lew
     
    Lew, Feb 23, 2009
    #2
    1. Advertising

  3. Composer

    Roedy Green Guest

    On Sun, 22 Feb 2009 20:26:23 -0800 (PST), Composer
    <> wrote, quoted or indirectly quoted someone who
    said :

    > System.out.println(PitchClassSet.toString(s)); // By now
    >it's been screwed up !!!
    > return s;


    I suggest you run your code in a debugger and trace the code, watching
    to see who buggers up s.
    Check your code for patterns like s = ????.
    That code is likely being executed between your constructor and your
    getSeries.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    One path leads to despair and utter hopelessness. The other,
    to total extinction. Let us pray we have the wisdom to choose correctly.
    ~ Woody Allen .
     
    Roedy Green, Feb 23, 2009
    #3
  4. Composer

    Mark Space Guest

    Composer wrote:
    > My class has an inner class as follows (irrelevant parts omitted):
    >
    > class ResultInstance
    > { private int[] s;
    >
    > // Constructor method
    > public ResultInstance(int[] series)
    > { s = series;
    > System.out.println(PitchClassSet.toString(s)); // At
    > this point it's fine !!!
    > }


    "s" here is not very private. You just copy the reference, not the
    whole array. Thus, after passing "series" into ResultInstances, if
    anyone then later changes "series", "s" will get changed too.

    You might want to do this:

    s = series.clone();

    which will clone the array for you, thus giving you a separate, private
    copy.

    Aside from that silly wild guess, Lew's right, you haven't given us
    nearly enough info to determine what has gone wrong. The getSeries()
    method also returns a reference, not a copy, which allows anyone to
    wreak havoc with your supposed "private" variable. Try cloning that
    too, see if the problems go away.
     
    Mark Space, Feb 23, 2009
    #4
  5. Composer

    Lew Guest

    Mark Space wrote:
    > "s" here is not very private. You just copy the reference, not the
    > whole array. Thus, after passing "series" into ResultInstances, if
    > anyone then later changes "series", "s" will get changed too.
    >
    > You might want to do this:
    >
    > s = series.clone();
    >
    > which will clone the array for you, thus giving you a separate, private
    > copy.
    >
    > Aside from that silly wild guess, Lew's right, you haven't given us
    > nearly enough info to determine what has gone wrong. The getSeries()
    > method also returns a reference, not a copy, which allows anyone to
    > wreak havoc with your supposed "private" variable. Try cloning that
    > too, see if the problems go away.


    Be careful - clone() makes a shallow copy. While the array won't change after
    implementing this fix, individual elements might.

    --
    Lew
     
    Lew, Feb 23, 2009
    #5
  6. Lew wrote:

    > Be careful - clone() makes a shallow copy. While the array won't change after
    > implementing this fix, individual elements might.


    Generally speaking, yes, but we are talking about an int[] here,
    where the copy is "deep" (in difference to an int[][]...)


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
     
    Lothar Kimmeringer, Feb 23, 2009
    #6
  7. Composer

    Composer Guest

    Many thanks to all, especially to Mark Space who led me straight to a
    resolution.

    I hadn't known about the clone() method of arrays.

    Nor had I known that "s = series" simply copied a reference from a
    different class.

    I'm happy to learn things like this. Sorry to have troubled anyone in
    the process.
     
    Composer, Feb 23, 2009
    #7
  8. Composer

    Lew Guest

    On Feb 23, 2:02 pm, Composer <> wrote:
    > Many thanks to all, especially to Mark Space who led me straight to a
    > resolution.
    >
    > I hadn't known about the clone() method of arrays.
    >


    'clone()' is a protected method of all Objects, except for those for
    which it has been elevated to 'public' access such as arrays.

    > Nor had I known that "s = series" simply copied a reference from a
    > different class.
    >


    That is a truism for all reference variables, except it's not "from a
    different class". When you assign any reference to a reference
    variable, it is the pointer that gets copied, not the instance to
    which it points.

    In order for the reference assignment to succeed, far from being "from
    a different class", the type of the source variable must be assignment-
    compatible with that of the destination variable. That means that
    they must either be of the same type, undergo a widening conversion
    (upcast)
    <http://java.sun.com/docs/books/jls/third_edition/html/
    conversions.html#5.1.5>
    or undergo a narrowing conversion (downcast) without a
    ClassCastException
    <http://java.sun.com/docs/books/jls/third_edition/html/
    conversions.html#5.1.6>
    ..

    --
    Lew
     
    Lew, Feb 23, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,800
    Thomas Weidenfeller
    Oct 12, 2005
  2. Schnoffos
    Replies:
    2
    Views:
    1,227
    Martien Verbruggen
    Jun 27, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,657
    Old Wolf
    Jan 20, 2004
  4. Carlo v. Dango
    Replies:
    14
    Views:
    1,046
    Alex Martelli
    Oct 19, 2003
  5. Pyenos
    Replies:
    2
    Views:
    392
    Pyenos
    Dec 27, 2006
Loading...

Share This Page