inner class loses track of int[] variable

C

Composer

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.
 
L

Lew

Composer said:
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.
 
R

Roedy Green

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 .
 
M

Mark Space

Composer said:
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.
 
L

Lew

Mark said:
"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.
 
L

Lothar Kimmeringer

Lew said:
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: (e-mail address removed)
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
 
C

Composer

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.
 
L

Lew

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>
..
 

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

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top