[1805] in java-interest
const (was: A few queries...)
daemon@ATHENA.MIT.EDU (Doug Lea)
Sun Sep 17 11:03:33 1995
Date: Sun, 17 Sep 1995 08:13:47 -0400
From: Doug Lea <dl@altair.cs.oswego.edu>
To: mlorton@eshop.com
CC: mason_l@ee.uwa.edu.au, java-interest@java.sun.com
In-reply-to: <199509151745.KAA05805@eshop.com> (message from Michael Lorton on
Fri, 15 Sep 1995 10:48:54 -0700)
> >
> > 1) Pass-by-value vs pass-by-reference vs pass-by-const-reference
> >
> Yeah, constancy was a curious omission from the language.
As Mark Linton once pointed out, this sense of C++ `const' is
basically syntactic support for a certain coding convention that can
also be had by partitioning methods into different classes. To get
the effect of C++ const methods, as in:
class A {
public:
void m1() const { ... }
void m2() { ... }
}
you could write in Java
class A {
public void m1() { ... }
}
class MutableA extends A {
public void m2() { ... }
};
A client operation, say
void use(A a)
can normally only access m1, even if `a' is actually of a subclass
supporting other methods (like m2).
But just as in C++, there's an intrinsic loophole. If `a' really
is of class MutableA, the use operation can access m2 by:
((MutableA)a).m2();
which is analogous to C++ `casting away const'.
There are other schemes that don't have this loophole, and so are
better when you really need to enforce such matters. This would be
true in C++ as well, except that you still couldn't protect yourself
from random pointer casts. But in Java, you can use interfaces plus
delegation to produce a fully secure const-style `view' of an object:
interface A {
public void m1();
}
class MutableA implements A {
public void m1() { ... }
public void m2() { ... }
}
final class ConstA implements A {
private A delegate;
public ConstA(A a) { delegate = a; }
public void m1() { delegate.m1(); }
}
A client like use(A a) could not possibly access m2() if it were
handed a ConstA, as in:
void app() {
MutableA ma = new MutableA();
...
use(new ConstA(ma));
}
There are several variants of this scheme as well. But generally, the
price you pay for such tight security is more classes and minor
performance hits. Still, this is usually more attractive than the
alternative of deep-copying passed objects (analogous to using C++
copy constructors), which often enough doesn't even make sense in
an application.
This is vaguely similar to how classes java.String and
java.StringBuffer are related. The fact that Strings are immutable
makes it easier to understand programs that use them. It would have
been nice if java builtin array types were structured along these
lines too, but it's not too hard to build classes on top of arrays
that do this. I'm hoping to make available soon a package of
collection classes and the like that, among other things, guarantee
immutablility when desired/required using a fancier variant of this
approach.
--
Doug Lea | dl@cs.oswego.edu | dl@cat.syr.edu | 315-341-2688 | FAX 315-341-5424
Computer Science Dept, SUNY Oswego, Oswego, NY 13126 | http://g.oswego.edu/dl/
Also: Software Eng. Lab, NY CASE Center, Syracuse Univ, Syracuse NY 13244
-
Note to Sun employees: this is an EXTERNAL mailing list!
Info: send 'help' to java-interest-request@java.sun.com