Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #25985
| Date | 2011-02-12 16:26 +0800 |
|---|---|
| From | Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> |
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: Object's properties changed |
| References | <0c26a62d-08b7-4149-a36b-ec3d9e6e8804@o14g2000prb.googlegroups.com> <d62dnUWFX6XMrcvQnZ2dnUVZ_tidnZ2d@posted.palinacquisition> <b572c4b6-2383-4093-a3c6-3feb778c6c1d@s11g2000prs.googlegroups.com> |
| Message-ID | <-eCdnSksr7G92cvQnZ2dnUVZ_rCdnZ2d@posted.palinacquisition> (permalink) |
On 2/12/11 3:28 PM, Vasu wrote:
> Hi Peter, thanks for your prompt reply, actually I'm newbie in Java
> programming field and just learning and I just tried the example @
> Oracle / java programming basics.
Can you please share the link to the example you are working from? Are
you talking about this section:
http://download.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
?
If that's the case, note that there should have been no reason to
implement your own Point and Rectangle types. As near as I can tell, the
example code does in fact work fine with the JDK types, and those are
the ones you should be using.
Note also that the JDK shows the "move()" method in the Rectangle class
as deprecated. That means you should avoid using it, and that it's
there only for backward-compatibility reasons.
> Thanks anyway once again and I will
> find how to achieve the objectives. But if you could suggest the code
> to be used here, will be highly appreciable.
This code most directly addresses your specific question (assumes you
continue to use the custom types, rather than the JDK types):
public class CreateObjectDemo {
public static void main(String[] args) {
//Declare and create a point object
//and 3 rectangle objects.
Rectangle rectOne = new Rectangle(new Point(23, 94), 100, 20);
Rectangle rectTwo = new Rectangle(50, 100);
Rectangle rect3 = new Rectangle(45, 45);
//display rectOne's y point
System.out.println("Original y point of rectOne: " +
rectOne.origin.y);
//set rectTwo's position
rectTwo.origin = new Point(23, 94);
//display rectTwo's position
System.out.println("Original X Position of rectTwo: " +
rectTwo.origin.x);
System.out.println("Original Y Position of rectTwo: " +
rectTwo.origin.y);
//display rect3's width, height, and area
rect3.origin = new Point(23, 94);
System.out.println("Original y point of rect3: " +
rect3.origin.y);
//move rectTwo and display its new position
System.out.println("Now we are moving rectTwo to a different place");
rectTwo.move(40, 72);
System.out.println("New X Position of rectTwo: " +
rectTwo.origin.x);
System.out.println("New Y Position of rectTwo: " +
rectTwo.origin.y);
//display rect3's width, height, and area
System.out.println("New y point of rect3: " + rect3.origin.y);
//display rectOne's y point
System.out.println("New y point of rectOne: " +
rectOne.origin.y);
}
}
The following code is IMHO a much better way to accomplish things (note
the use of the JDK types, rather than the custom types you defined):
import java.awt.Point;
import java.awt.Dimension;
import java.awt.Rectangle;
public class CreateObjectDemo {
public static void main(String[] args) {
//Declare and create a point object
//and 3 rectangle objects.
Point origin = new Point(23, 94);
Rectangle rectOne = new Rectangle(origin, new Dimension(100, 20));
Rectangle rectTwo = new Rectangle(50, 100);
Rectangle rect3 = new Rectangle(45, 45);
//display rectOne's y point
System.out.println("Original y point of rectOne: " +
rectOne.getY());
//set rectTwo's position
rectTwo.setLocation(origin);
//display rectTwo's position
System.out.println("Original X Position of rectTwo: " +
rectTwo.getX());
System.out.println("Original Y Position of rectTwo: " +
rectTwo.getY());
//display rect3's width, height, and area
rect3.setLocation(origin);
System.out.println("Original y point of rect3: " +
rect3.getY());
//move rectTwo and display its new position
System.out.println("Now we are moving rectTwo to a different place");
rectTwo.setLocation(40, 72);
System.out.println("New X Position of rectTwo: " +
rectTwo.getX());
System.out.println("New Y Position of rectTwo: " +
rectTwo.getY());
//display rect3's width, height, and area
System.out.println("New y point of rect3: " + rect3.getY());
//display rectOne's y point
System.out.println("New y point of rectOne: " +
rectOne.getY());
}
}
Note in the above that even though the same Point object is used in
several places, the object itself is not referenced except as long as
necessary to copy the values from it into the x and y fields of the
Rectangle object. You can modify the Rectangle later without affecting
other instances of Rectangle, even those that were initialized using the
original Point object.
Whether seeing code that works as you expect it to will help you
understand the original problem, I have no idea. I hope it does. But
if not, it may help you to keep in mind that variables having a class
type are only _references_ to an object; they don't contain the state of
the object itself, but rather a reference to an object elsewhere in memory.
This means that if you have more than one variable that has been
assigned to the same object (as in the "origin" variable in your made-up
Rectangle class), then if you change that object via one of the
variables, every other place that is referring to the same object will
effectively be changed as well. That is, while the reference itself
doesn't change, they are all referring to the same object, and so if you
examine the object via any of those references, you're going to see the
same exact state.
This is why modifying the state via one Rectangle object causes all the
others to wind up with the same new state. They are sharing the same
Point object for their "origin" value.
The first example above fixes the problem by creating a new Point object
for each Rectangle object. That way, when you change the state of the
"origin" object for one, it affects only that Rectangle.
The second example fixes the problem in what is IMHO a much better way:
it avoids the problem altogether by using the JDK Rectangle type, which
stores the entire object state in primitive types (i.e. int), rather
than in an object. Primitive types are only ever copied; you don't get
references to them. So every Rectangle object necessarily will always
have its own individual x, y, width, and height values. You never have
to think about whether two or more Rectangle objects are sharing
references to a common Point object, because they don't have a reference
to a Point object in the first place.
Note that yet a third way to address the problem would be to make the
Point object "immutable". That means that once you've created it, you
can't change it. For example, had you declared your custom Point object
as this:
class Point {
public final int x;
public final int y;
//constructor
public Point(int a, int b) {
x = a;
y = b;
}
}
Note the "final" modifier on the x and y fields. This means the x and y
fields could not be changed after the Point object has been created.
Then to change the origin of a Rectangle, you would have been forced to
create a new Point object, and assign it to the origin field. This
would necessarily ensure that any time a Rectangle's origin is changed,
it's done so without affecting any other Rectangle instance.
See the java.lang.String for an example of a very common, widely-used
immutable type in the JDK. :)
Pete
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Find similar
Re: Object's properties changed Vasu <vasudevmukherjee@yahoo.co.uk> - 2011-02-11 23:28 -0800 Re: Object's properties changed Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2011-02-12 16:26 +0800
csiph-web