Why not cloneable by default?

C

Chris Smith

Thomas said:
If you ask if two integers are equivalent, do you care that they are
different integers that merely have the same value? No.

Yep, and hence instances of class java.lang.Integer are *values*; they
don't really possess identity in a meaningful sense. They are objects
only as an implementation detail. The ability to compare two Integer
objects and determine that they are distinct from each other is
completely useless. As a consequence, the ability to have two Integer
objects with the same state but different identity (i.e., cloning) is
equally useless.
The notion of equality is one of current-value, or current-state.
Mutability is fine for equality.

If equality were universally used this way, that would be fine. In
practice, though, a HashSet cannot hold two objects that compare equal
to each other. If "equal" only meant comparing what happens to be the
current state of the two objects, that would be a rather pointless and
even idiotic restriction.
And I would counter that you need object state comparisons far more often
than you need true object (reference) comparisons.

I certainly don't find that to be true. The simple fact that fewer than
10% of classes in the Java core API override equals(Object) tends to
back up that observation; identity comparison is by far the more common
requirement.

None of the Swing components ever compare equal to each other,
regardless of how similar their state is. Even pure data classes such
as DefaultTableModel fail to override equals. A brief through other
packages (security, I/O, etc) yields similar facts. Classes that do
override equals(Object) are, generally speaking, values in exactly the
same manner as Integer is a value.

That only leaves you with a couple screw-ups: Date, etc. They are
widely admitted to be mistakes, generally in the direction of making
them too object-like. And there's the Collections API, which is just
odd given that it was created with the benefit of hindsight, but is
still equally wrong.

All together, even with mistakes, that makes up a very small percentage
of classes that ever compare equal to anything but themselves. And that
fits the occasions where equals(Object) is used in the core API very
well.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Patricia Shanahan said:
How do you feel about e.g. java.util.ArrayList. Two List
objects are equal if they contain the same references in the
same order, yet ArrayList is Cloneable. Which feature would
you drop?

As is probably clear by now, I disagree with their being equal.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

The heart of the matter first:
Chris Smith wrote:
Why should the client code need to be aware of this subset? The
purpose of a virtual equals() method is to encapsulate this sort of
information within the class most suited to dealing with this, namely
the class on which you invoke the equals method.

Because it's the client code that wants to compare that subset, and the
client knows what it should do. The set of object state that is
compared is *not* some kind of intrinsic quality of the object itself,
and it is not most suited to be defined by the object itself. It is a
decision about how that object is being used, and is proper to the
client. Fundamentally, classes that override equals(Object) for a less-
than-complete comparison are making assumptions about how they will be
used from client code, and it's a real pain when they guess wrong.
Presumably, the employees would be compared on an employee number
rather than name and salary?

Employees of MindIQ (my employer) don't have an employee number. What
happens now?

More abstractly, a fundamental principle of object-oriented design is
that objects own behavior, state, and identity... and when you take away
their identity, you are begging for problems and making the space more
complex. Of course, in reality, no one does that all of the time. It
just happens randomly here and there. That here and there causes
problems, though, when an object gets used in an unanticipated way.
If you have an entity in your problem domain that has a number of
properties that define the object's identity and a number of different
properties that help define the object's current state, then surely
the equality testing should only be taking the former into account?
And if these identifying properties are immutable, then why is there a
problem?

In that case, the properties defining the identity should be
encapsulated, and the data structure should accomodate. To give an
example...
If I am looking for a particular car, then surely I want to be
comparing on the immutable "registration number" property rather than
on the mutable "current location" property?

I can't possibly imagine how you expect to find a car by registration
number using some kind of other Car instance to compare against. Are
you going to create some kind of dummy Car object with only partial
state, and then use it to compare?

Why not keep a hash table that finds a Car by its registration number?
The registration number properly compares equal, and you don't have to
create weird phantom cars that exist only to be compared and have
incomplete state.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

That isn't true unless you're programming applets or in some other restricted
environment.

Hmm, interesting thought. Of course, Java's security arises entirely
from its being used where "you're programming applets or in some other
restricted environment." I don't think your qualification really limits
the scope of Tim's statement in any significant way at all.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Thomas G. Marshall

Chris Smith coughed up:
The heart of the matter first:



Because it's the client code that wants to compare that subset, and
the client knows what it should do.

The client wants to know that two BigThingy's are equal. It may be
documented that it is the /value/ that is compared. It's the BigThingy that
knows what that really means.

The set of object state that is
compared is *not* some kind of intrinsic quality of the object itself,
and it is not most suited to be defined by the object itself. It is a
decision about how that object is being used, and is proper to the
client. Fundamentally, classes that override equals(Object) for a
less- than-complete comparison are making assumptions about how they
will be used from client code, and it's a real pain when they guess
wrong.

No, I believe you still have this backwards. Regardless of how the client
believes it ought to be used, it is the class (object) that knows what
values within itself to compare.

I can imagine some objects that have very different rules about what
constitutes equal who's details should stay out of the hands of the client.

Employees of MindIQ (my employer) don't have an employee number. What
happens now?

More abstractly, a fundamental principle of object-oriented design is
that objects own behavior, state, and identity... and when you take
away their identity, you are begging for problems and making the
space more complex.

It is /part/ of a java object's behavior to compare itself in its own way
via equals(), should it override it.

The only problem I have with equality is that it so strongly needs
documentation to describe what it means. But I see no way around this.

....[rip]...
 
T

Thomas G. Marshall

Chris Smith coughed up:
As is probably clear by now, I disagree with their being equal.

And what if I /DID/ need to check that two lists contained the same
references in the same order? There would be some terminology and method
call to represent this. And if you don't like equals(), then what would you
prefer? cellsAreEqualTo(List)? Is your objection rooted in that there is
one method name (equals()) to mean many possible different things?
 
T

Thomas G. Marshall

Chris Smith coughed up:
Thomas said:
Chris Smith coughed up:

...[rip]...
If a class is
immutable, it should not be exposing clone().


What does immutability (the ability to be altered) have to do with
cloneability (the ability to be duplicated)?

Why would you clone an immutable object?


Point taken.

There would need to be an algorithm that required elements in some data
structure where having reference equality meant one thing, and value
equality another. In which case it'd be possible to want two different
objects of the same immutable value from time to time.
 
C

Chris Smith

Thomas said:
And what if I /DID/ need to check that two lists contained the same
references in the same order?

Well, in hypothetical-land where this contract doesn't exist for
java.util.List, there would almost certainly be a standard API
Collections.compare(List,List) method to do the job for you.
There would be some terminology and method
call to represent this. And if you don't like equals(), then what would you
prefer? cellsAreEqualTo(List)? Is your objection rooted in that there is
one method name (equals()) to mean many possible different things?

Yes!

To pin it down precisely, my objection is not to the method name
"equals", which is vague enough to encompass a lot of different
meanings. I object to defining an incomplete concept of equality when
that same equality is going to be used by the core API as if it were
sufficient to recognize all of the important differences between two
objects.

It's precisely that fact -- that Object.equals is widely used to ask
about the *equivalence* of two objects -- that makes it wrong for
mutable objects to call themselves equal with that method. By being
mutable, those objects are *not* equivalent... and there are numerous
places where it's consequently assumed that they are.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
L

Lasse Reichstein Nielsen

If I am looking for a particular car, then surely I want to be
comparing on the immutable "registration number" property rather than
on the mutable "current location" property?

But then how would two different car objects with different "current
location" properties represent the same car (which can only be in one
location at a time :)?

If you have such two objects, then they represent the car at different
times, and your class is not modelling a car, but a history of car
locations.

Modelling actual objects is best handled by letting object identity
(in Java) represent the object.
What exactly is it you are expecting the equals() method to represent?
I expect it to be an equality test that takes into account the type of
the object and the set of properties that best identifies it and
ignores other non-identifying properties. Is your expectation
different?

Perhaps stricter, depending on how non-identifying properties are
defined.

The equals() method defines an equality relation on a group of objects,
not necessarily of the same class, but related by design.

If two objects are equal, it should never matter which one you use.
If you add one of them to a set, it means that the other one cannot
be added, so either one should be sufficient for all algorithms using
them.


An "almost immutable" object, where a few "administrative" properties,
not related to the object's primary purpose (e.g., counting accesses
to a method), could reasonably use an equals() that only checks the
primary properties.

In such a situation, the extra administrative functionality and
properties could be removed without breaking the primary behavior of
the object (and it would probably not be cloned either).

If this is "non-identifying" properties, then I can agree, but they
should be realtively rare.

/L
 
C

Chris Uppal

John said:
1) The cloning mechanism shall produce from an object a distinct object
of the same class that is logically a copy of the original.

I think that this condition is too strong. If we weaken it to allow an
implementation of copy as:

public <whatever> copy() { return this; }

then the system will work more gracefully.

The 'copy' operation is not a precisely defined operation -- there is no
God-given (or Gosling-given) single idea of what a 'copy' is. So the method
called copy() can only ever represent a class-designers /best guess/ at what is
/likely/ to be most useful to users of that class. In particular, the amount
of state that is replicated (as opposed to shared) between the original and the
copy is not something that can be decided by some global policy. The degree of
'deepness' needed for a copy is determined (even ignoring context) by private
details of the object's implementation, and by the mapping between the objects
state and its semantics. For instance a Rectangle class that internally
maintains its definition/state as two fields of class Point should obviously
(for most normal purposes) implement copy as a fully deep operation. OTOH, a
ColoredRectangle that implemented its state as 4 floats and a Color would
probably implement copy as shallow.

Note that how much state is replicated depends (in part) on details that are
private, and hence the caller (in many circumstances) would be wrong to attempt
to dictate how much of the state is replicated vs. shared.

(Incidentally, that's why I object to, and have avoided using, the method name
clone() -- which I think strongly implies a particular strategy for copying,
and one that is not necessarily appropriate.)

I think that the limiting case of shallowness is a "copy" that replicates no
state, and shares all state. I.e.
return this;

That turns out to be a natural implementation of "copy" for genuine Singletons
(if there are any ;-). And -- much more importantly -- for any object which is
intended to act as the "sole representative" of some other entity. This
interpretation of copy() is that it should return an object that is as distinct
/as semantically possible/ from the original (up to some context and
implementation-dependent limit on deepness). The limiting case of "distinct as
semantically possible" is /no/ difference; if the only semantically valid
"equivalent" of some object is that object itself, then that's what the "copy"
should provide.

Returning to the ColoredRectangle. I said that it would probably implement
copy as a shallow copy (a pure clone()), but really that's a design error.
Rectangle /might/ know how Colors work, and whether the best way to get a
duplicate 'handle' on a colour is simple to copy the reference. It's not
entirely implausible that it /would/ know that, but I don't think it should
/have/ to know it. If Colors are expensive (not likely I admit) then it would
be an entirely plausible design that Color provided a number of pre-defined
instances that (purely for efficiency reasons) should remain unique --
Color.RED, Color.BLUE, -- but that less commonly used instances would be
created on-the-fly and discarded at need. But that's not possible if classes
like Rectangle are going to second-guess what it means to copy a colour. So
the implementation of ColoredRectangle.copy() should also copy() the Color.
The implementation of Color.copy() would just "return this;" (assuming that the
objects were immutable, and if the class designer had thought it worthwhile to
implement an optimised version of copy()).

Anyway, with all that out of the way. How about the following, as a
start-point ?

public class Object
{
....

// the JVM-level clone operation
private native Object __clone();

protected final Object clone()
throws CloneNotSupportedException
{
if (this instanceOf NotClonableMarkerInterface)
throw new CloneNotSupportedException();
return this.__clone();
}

public Object copy()
throws CloneNotSupportedException
{
Object copy = this.clone();
copy.postClone();
return copy;
}

protected void postClone()
{
// default is no action
}

...
}

Some notes:

1) I'm not completely convinced that it's ever appropriate for an object to be
marked with NotClonableMarkerInterface. There may /be/ a good reason, though,
so I've left the test-and-throw in for now. Unless a good use for it can be
found, though, (perhaps something to do with security) then I think it would be
much better to get rid of it and CloneNotSupportedException.

2) I'm not completely convinced that the clone() method should be available to
subclasses at all. It might be better to make clone() private, and change the
copy implementation to something like:

public final Object copy()
throws CloneNotSupportedException
{
if (this instanceOf SingularInstanceMarkerInterface)
return this;
Object copy = this.clone();
copy.postClone();
return copy;
}

but that /reeks/ of over-engineered brittleness to me...

3) Subclasses have the choice of overriding copy(), which they would do if they
wanted to
return this;
or if -- for whatever reason -- they knew a better way to implement copying
than going via the system-level clone() operation.

4) ... or they could override postClone() to do any massaging of the results of
clone() that were necessary to preserve sanity. Nearly all implementations
would take the form:

protected void postClone()
{
m_field1 = m_field1.copy();
m_field6= m_field6.copy();
//...
}

5) In the above I've assumed that the copy() operation should be universally
available. That way seems best to me (especially in a language which makes the
equally problematical equals() method public). The main reasons for
restricting it seem to be that (a) the semantics are /not/ obvious so users
should be forced to think before using it, (b) some objects should not be
copyable. The point (a) is valid, but I don't think that restricting copy()
actually helps. And, as I've said, with the extended interpretation of copy()
that I'm urging, I think that most (perhaps all) of the examples of
non-copyable object evaporate.

6) But, that said, I don't really see much harm in including an /unchecked/
CopyNotSupportedException that subclasses could override copy() to throw.

If we think that copy() should not be supported by default, then I'd just
remove copy() (and postClone()) from Object, add an interface
interface Copyable
{
Object copy();
}
that subclasses could implement at will.

(Incidentally, that pattern and interpretation of "copy" is taken (with
considerable simplification) from Smalltalk. The pattern works well there, but
I wouldn't want to over-state the relevance of that observation since Smalltalk
makes /much/ heavier use of non-cloneable objects than Java does. E.g. the
Integer object 12 cannot be copied, but it does /have/ to be polymorphic with
other objects that /are/ copyable, so implementing copy as "^ self" (i.e.
"return this;" in Java-speak) is the only realistic option).

-- chris
 
B

Bent C Dalager

Because it's the client code that wants to compare that subset, and the
client knows what it should do. The set of object state that is
compared is *not* some kind of intrinsic quality of the object itself,
and it is not most suited to be defined by the object itself. It is a
decision about how that object is being used, and is proper to the
client. Fundamentally, classes that override equals(Object) for a less-
than-complete comparison are making assumptions about how they will be
used from client code, and it's a real pain when they guess wrong.

Here we are touching upon some of the same issue as we have with the
notion of a "natural ordering". If it can be assumed that a given
class can define a natural order for its instances, can we not also
assume that it is possible to define a natural equality test? I don't
see why this is not a useful concept.
Employees of MindIQ (my employer) don't have an employee number. What
happens now?

You give them one. How can you tell one John Smith from another if
they don't have some well-known distinguishing feature? You could
possibly tell them apart by calling one of them "John Smith with the
dark hair", but that is cumbersome and far from a general solution.
More abstractly, a fundamental principle of object-oriented design is
that objects own behavior, state, and identity... and when you take away
their identity, you are begging for problems and making the space more
complex. Of course, in reality, no one does that all of the time. It
just happens randomly here and there. That here and there causes
problems, though, when an object gets used in an unanticipated way.

I don't see how you are taking away identity. If anything, you are
defining their identity by specifying exactly what it is that makes
each instance unique.
I can't possibly imagine how you expect to find a car by registration
number using some kind of other Car instance to compare against. Are
you going to create some kind of dummy Car object with only partial
state, and then use it to compare?

It is going to happen if I found a car in one location and another car
in a different location and want to know if it was the same car. I
might have gotten one reading from each of two different automatic
speed cameras, for instance.
Why not keep a hash table that finds a Car by its registration number?
The registration number properly compares equal, and you don't have to
create weird phantom cars that exist only to be compared and have
incomplete state.

Searching algorithms are certainly related to this, but they are not
the only situation in which you need to compare objects.

I expect that in a complex system, you will have a number of different
ways of searching for an object. One of those ways _may_ have been
defined as the "natural" way of comparing two objects of that type.

So for cars, you could search on registration number but you could
presumably also search on make, model, colour, etc. This fact doesn't
make the concept of a natural identity less useful.

Cheers
Bent D
 
B

Bent C Dalager

An "almost immutable" object, where a few "administrative" properties,
not related to the object's primary purpose (e.g., counting accesses
to a method), could reasonably use an equals() that only checks the
primary properties.

In such a situation, the extra administrative functionality and
properties could be removed without breaking the primary behavior of
the object (and it would probably not be cloned either).

If this is "non-identifying" properties, then I can agree, but they
should be realtively rare.

Ok, so if I am reading your right, you would accept mutable properties
so long as they don't really matter. In serialization terms, anything
that is declared "transient" can perhaps happily be mutable.

I agree that I use a more relaxed requirement and this is almost
certainly the cause of the current disagreement.

Cheers
Bent D
 
J

John C. Bollinger

Lee said:
Chris Smith wrote:


Interesting question. It looks obvious you wouldn't. However, it seems appropriate (for
an immutable object) to implement Clonable, so certain deep copies will work. An
immutable object would just return itself. Seems strange at first, but I like it.

In our consideration of the appropriate specification for a better
cloning mechanism, then, are you suggesting that we drop the requirement
that a clone be distinct from the original object?
 
C

Chris Smith

Bent C Dalager said:
Here we are touching upon some of the same issue as we have with the
notion of a "natural ordering". If it can be assumed that a given
class can define a natural order for its instances, can we not also
assume that it is possible to define a natural equality test? I don't
see why this is not a useful concept.

This is sort of the same issue... and while a class can declare a
certain natural ordering, it's also true that in *every* standard API
situation where Comparable is used, you've also got the option to use
Comparator instead. Essentially, Comparable is just a convenience, and
one that can be afforded because you could always do things the long
way, too, if that were necessary.

Now look at equals(Object). It's not a convenience method in the same
sense as compareTo, and it's only use within the standard API is to
detect objects that are completely equivalent to each other (as in, it
doesn't matter which of these two objects you have).
You give them one.

I look forward to your telling my boss that he should assign all of us
employee numbers because not doing so would conflict with your ideas on
programming in Java.
How can you tell one John Smith from another if
they don't have some well-known distinguishing feature? You could
possibly tell them apart by calling one of them "John Smith with the
dark hair", but that is cumbersome and far from a general solution.

That's not the point here. How you believe my boss should run his
company is entirely immaterial. The point is that you are throwing away
the ability to run the company in the way that we do, which limits the
expressive power of the language.

That relates to...
I don't see how you are taking away identity. If anything, you are
defining their identity by specifying exactly what it is that makes
each instance unique.

That is exactly what is NOT MEANT by the fundamental OO principle of
objects owning their identity. Identity is its own property of an
object, and is *not* a consequence of its state. Without understanding
this, the best that be accomplished is development in some kind of
pseudo-OO paradigm; a kind of weird cross between OO and the relational
model.

What you're doing is exactly what I said: you are pretending that
objects don't have their own identity, independent of state. Then yoiu
are insisting that the problem domain must be modified to add its own
concept of some identifying characteristic. The latter, of course, is
only necessary because you're neglecting the former. It's also
unlikely, unless you're completely restructuring the business, that
you'll achieve a change in the problem domain to fit your requirements.

Certainly, you could circumvent this by introducing your own internal
employee ID. This is commonly done, in fact, in relational databases...
where it is called surrogate keys, and is used to work around the fact
that TUPLES DON'T HAVE IDENTITY. Any such technique in OO modeling,
though, is highly suspect because the OO model provides a mechanism for
preserving the identity of objects without relying on naturally
identifying state.
It is going to happen if I found a car in one location and another car
in a different location and want to know if it was the same car. I
might have gotten one reading from each of two different automatic
speed cameras, for instance.

In that case, you've got one Car, and two Readings. If you use the same
Car object for both pieces of state, then your design is a bit odd.
Nevertheless, it would still be wrong to override equals(Object) and
compare only the car and ignore the actual location and reading of the
camera.

Elsewhere in the same application, you may need to compare the identity
of these objects and determine if they really are equivalent (i.e., they
represent the same record of this Car at this location at this time).
You now have no way of doing that.
Searching algorithms are certainly related to this, but they are not
the only situation in which you need to compare objects.

I was guessing at how you intended to use such an object, because you
didn't say.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

John C. Bollinger said:
In our consideration of the appropriate specification for a better
cloning mechanism, then, are you suggesting that we drop the requirement
that a clone be distinct from the original object?

I'm not sure I agree... but if so, then the requirement might instead
say "operations on the clone() will not directly affect the results of
operations on the original object". That would allow for the no-op
"cloning" of immutable objects, or objects whose only state is some kind
of internal logging or something like that, but still address most
interesting uses of clone().

As I said, though, I'm not sure I agree. I'd have to think more about
it.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
P

Patricia Shanahan

Chris Uppal wrote:
....
1) I'm not completely convinced that it's ever
appropriate for an object to be marked with
NotClonableMarkerInterface. There may /be/ a good
reason, though, so I've left the test-and-throw in for
now. Unless a good use for it can be found, though,
(perhaps something to do with security) then I think it
would be much better to get rid of it and
CloneNotSupportedException.
....

I quite often have a class where I know a good,
class-appropriate copy would cost some thought and
implementation effort, but I don't know of any reason to
copy its objects. I don't like the idea of leaving
inappropriate copy methods lying around. Currently, I just
don't mark them Cloneable. How should those cases be handled?

Not directly related to Chris' article, but something that
should be considered whenever deep copy is discussed: What
happens when object A has two references, through different
structures, to object B. Should each be copied separately,
or should A have two references to a single copy of B?

For example, see the thread "Hashtable/Two keys", concerning
rapid lookup by two different key schemes, where both keys
are known at insertion time but only one key is known for
lookup.

Patricia
 
B

Bent C Dalager

This is sort of the same issue... and while a class can declare a
certain natural ordering, it's also true that in *every* standard API
situation where Comparable is used, you've also got the option to use
Comparator instead. Essentially, Comparable is just a convenience, and
one that can be afforded because you could always do things the long
way, too, if that were necessary.

Now look at equals(Object). It's not a convenience method in the same
sense as compareTo, and it's only use within the standard API is to
detect objects that are completely equivalent to each other (as in, it
doesn't matter which of these two objects you have).

I would agree that we could do with a decent way of overriding the
notion of equality for special cases, much as we do for ordering. As
it stands, we are largely stuck with putting objects into wrappers or
other surrogate objects that define their own equals. Which is ugly.
I look forward to your telling my boss that he should assign all of us
employee numbers because not doing so would conflict with your ideas on
programming in Java.

This has nothing to do with any particular language. It is a feature
of the problem domain. If you have two or more people with the same
name, you need to have _some_ strategy for telling them apart. If not,
when you tell the HR person you want John Smith on your project, you
risk ending up with the John Smith who does building maintenance, not
John Smith the UML expert that you actually wanted.

My company uses unique initials to resolve this problem. The first
John Smith might get the initials JS. The other might get JoS or
JSm. We also have employee numbers, but those are for the boys and
girls in accounting. Initials are easier to remember for ordinary
people most of the time.
That's not the point here. How you believe my boss should run his
company is entirely immaterial. The point is that you are throwing away
the ability to run the company in the way that we do, which limits the
expressive power of the language.

If your boss insists on having a computer system that cannot tell
people apart, I am sure that could be accommodated. It might not be
very useful, but it would be possible.
That is exactly what is NOT MEANT by the fundamental OO principle of
objects owning their identity. Identity is its own property of an
object, and is *not* a consequence of its state. Without understanding
this, the best that be accomplished is development in some kind of
pseudo-OO paradigm; a kind of weird cross between OO and the relational
model.

What is the fundamental difference between a property of an object and
the object's state? I would have thought that one or more of the
former is what makes up the latter?
In that case, you've got one Car, and two Readings. If you use the same
Car object for both pieces of state, then your design is a bit odd.
Nevertheless, it would still be wrong to override equals(Object) and
compare only the car and ignore the actual location and reading of the
camera.

Elsewhere in the same application, you may need to compare the identity
of these objects and determine if they really are equivalent (i.e., they
represent the same record of this Car at this location at this time).
You now have no way of doing that.

If I have defined one natural identity and I find I need other
comparisons as well, then I would certainly have to implement them. I
don't see why this is a problem. It is not intended that the natural
equality algorithm should be a silver bullet, useful for all possible
applications. It is only meant to be the most natural way of looking
at the object.

Cheers
Bent D
 
J

John C. Bollinger

Lee said:
Thanks, John, though this may be an exercise in futulity we could at least submit it to
JCP (is there nothing at this point?)

If we actually get anywhere useful, then I do hope to transfer the
results to the JCP. As far as I can tell, there really isn't any
existing JSR that is already addressing the issue.
Would you add an issues/questions section? My contribution would be to add Chris's about
shallow/deep cloning potentially being a consideration outside of the class
implementation ... while still being controlled by the class.

Does the summary document I refer to in my last post adequately address
your request?
 
J

John C. Bollinger

Chris said:
I'm not sure I agree... but if so, then the requirement might instead
say "operations on the clone() will not directly affect the results of
operations on the original object". That would allow for the no-op
"cloning" of immutable objects, or objects whose only state is some kind
of internal logging or something like that, but still address most
interesting uses of clone().

Yes, that is exactly the kind of requirement I had in mind for a
replacement.
As I said, though, I'm not sure I agree. I'd have to think more about
it.

I find Lee's and Chris Uppal's arguments on the topic persuasive, but
I'm not yet sure either.
 

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,780
Messages
2,569,608
Members
45,246
Latest member
softprodigy

Latest Threads

Top