object relational database versus "inteligent" serialization

L

luc peuvrier

joafip is based on red-black tree, it use a heap implementation
( indexed binary data record ).
About performance in 2008 I made the following measurement
http://joafip.sourceforge.net/perf/perf.html
The object saved have few bytes. For the test a TreeMap is persisted.
A colleague validate the performance for our application usage, he was
more worry about hibernate/postgres performance when integrating item
table. I have not value to give to you.

Luc
 
P

Pitch

It would have to be - you cannot construct an object unless all its superclass
aspects are constructed, in Java's case before subclass aspects.


Why does it suck?

You cannot override any constructor, not default, not explicit no-arg, not
with args.


Again, why does that suck?


You do, if you give it two minutes' thought. You call a method or do whatever
in a constructor after the object has reached a certain level of construction.
In order to reach that level, the superclass aspects have to be constructed
first, even to reach the subclass's constructor aspect. If you want something
other than default superclass construction, you have to do it first.


So you all say it's a safety thing, right? It forces a design where
initialization of an object gurantees that all inherited initializations
will execute first.

Nice. ;)

But many other languages allow you to override constructors! Are they
old, obsolete?

Are there any other reasons besides good design?

If we talk about errors that may occur if you could override a
constructor then we could say those same erros could occur if you
override any other protected method.

Why is proper construction sequence so important? Why not just leave it
to access modifiers? Wouldn't that be more straightforward than having
silly rules like "super() must be the first line"??

I mean, if it's a call, and not a syntax issue I'd like to write it
wherever I like. Let _me_ worry about proper initialization. :)
 
L

Lew

Pitch said:
So you all say it's a safety thing, right? It forces a design where

Not exactly. It's more like there has to be an object before you can call
methods on it. (The area where I was wrong.) There has to be an object
before you can do anything at all to it, really.
initialization of an object gurantees that all inherited initializations

Construction, of which initialization is a part.
will execute first.

That's just the way Java is designed. There are tradeoffs to construction
parent-first vs. subclass-first. The Java approach simplifies things, but as
you see, you have to use static methods to accomplish fancy logic in a 'super(
foo )' call.
But many other languages allow you to override constructors! Are they
old, obsolete?

Which languages?

The answer to that will tell you if they're old or obsolete.
Are there any other reasons besides good design?

No doubt. Mainly it's to ensure that anything you do on an instance happens
on completely-constructed parts.
If we talk about errors that may occur if you could override a
constructor then we could say those same erros could occur if you
override any other protected method.

Not true. First of all, you have to bear in mind that you cannot override
constructors in Java, nor inherit them.

As for overriding any other non-private method, there is a difference between
the errors that occur when an object is not constructed yet vs. once it's
completely built.
Why is proper construction sequence so important? Why not just leave it
to access modifiers? Wouldn't that be more straightforward than having
silly rules like "super() must be the first line"??

No. And calling the rule "silly" doesn't make it so. Several have answered
you to explain why it's not silly. That you call it that now, after having
read those replies, means that you are being obstinate. The reasons behind
the decision are sound, and like all engineering decisions, do involve
tradeoffs. That you are not able to perform some idiosyncratic action that
only you really want to do does not make Java's decision silly.

As for "leaving it to access modifiers", that would not address at all what
construction order addresses. You can put access modifiers on constructors;
that has no effect on construction order. The purpose of construction order
is to make sure that an instance exists before you do stuff to it. The
purpose of access modifiers is to affect access, whether before, during or
after construction.

And no, it would not be more straightforward than constructing objects from
the inside out. Allowing code prior to superclass construction, or this-class
construction for that matter, would complicate matters horribly.
I mean, if it's a call, and not a syntax issue I'd like to write it
wherever I like. Let _me_ worry about proper initialization. :)

I really don't think that would be wise.

What do you mean by "a call, and not a syntax issue"?

In fact, the issue of construction order is neither, whatever you might mean
by that. It's a matter of having an object on which to act.
 
E

Eric Sosman

So you all say it's a safety thing, right? It forces a design where
initialization of an object gurantees that all inherited initializations
will execute first.

Nice. ;)

But many other languages allow you to override constructors! Are they
old, obsolete?

Appealing to "other languages" isn't of much use. Many
other languages, for example, have `goto'.
Are there any other reasons besides good design?

If we talk about errors that may occur if you could override a
constructor then we could say those same erros could occur if you
override any other protected method.

Since Java cannot prevent all errors, is it your belief that
it should not bother trying to prevent any at all?

As to the "any other protected method" remark, note that a
constructor is not a method despite many surface similarities.
Why is proper construction sequence so important? Why not just leave it
to access modifiers? Wouldn't that be more straightforward than having
silly rules like "super() must be the first line"??

1: So a class can establish its invariants, and not worry
about a subclass messing them up. (1a: So a subclass can rely
on its superclass to operate as advertised, without the subclass
needing to take on the responsibility for correct operation.)

2: I don't understand the suggestion. What does access have
to do with sequencing? Accessibility is a static attribute, not
a time-varying property. (Absent skulduggery, that is.)

3: Since I don't understand (2), I can't tell whether it
would be less silly.
I mean, if it's a call, and not a syntax issue I'd like to write it
wherever I like. Let _me_ worry about proper initialization. :)

No, because I don't trust you. I've written my class, and
you're extending it, and I have no idea whether you know enough
about my class' internals to be able to duplicate them in your
code. (In fact, I've used an obfuscator on my class' byte code
specifically to conceal those internals from you. If you know
enough about them to replace bits and pieces at will, you must
have worked hard to reverse-engineer the code in violation of
your license, and my attorneys will be in touch with you.)

Even without the licensing and trade secrets stuff, think
of the position you're putting the superclass' author in if you
allow any old subclass to muck with the internals. Some user
reports that there's a bug in my class; I say "Thanks for the
report" and send a fix. The fix involves adding a new private
reference variable, and having the constructor initialize it to
point to something useful. Other methods then use that variable
to get at the useful goodies, and my fix solves the problem.

... except that you have somehow overridden my constructor
(you clever devil), so my constructor's code never runs and the
added reference remains null. When another method comes along,
there's a NullPointerException and I get another bug report from
a user who's becoming very angry at my inability to fix things.
I guess from your perspective this is a Good Thing: You've made
the mistake of failing to read my mind and anticipate all my
fixes, but I take the heat for your failure!

No, thanks, Pitch. I'm too egotistical about my own code
to allow you to inject yours into the middle of it and then get
me to take the blame.
 
A

Arne Vajhøj

Or int/long and establishing a convention that you're working in pence,
or thousandths of a dollar, or whatever is suitable.

Yes, but why bother when BigDecimal already handle it.

Arne
 
A

Arne Vajhøj

Huh, this bit is interesting. Why is main memory and disc memory
constrained?

Are you working in a restricted environment like JME?

Java ME ??
Why is it better for your manager to pay you for several hours for work,
rather than to just go to the store and buy 2Gb of memory for $100?
(Which should be, what, worth one and a half hours of your time, minimum?)

It is less these days.

I would say that for servers that is how the math is. But there are
low end laptops today that is sold with just 1 GB.

Arne
 
P

Pitch

esosman@ieee-dot- said:
Appealing to "other languages" isn't of much use. Many
other languages, for example, have `goto'.

Which does not exclude they could have good stuff too.
Since Java cannot prevent all errors, is it your belief that
it should not bother trying to prevent any at all?

No, I just want to know why.
1: So a class can establish its invariants, and not worry
about a subclass messing them up. (1a: So a subclass can rely
on its superclass to operate as advertised, without the subclass
needing to take on the responsibility for correct operation.)

If subclass messed them up it is the same thing as the caller messed
them up. That's why we do input validation.
2: I don't understand the suggestion. What does access have
to do with sequencing? Accessibility is a static attribute, not
a time-varying property. (Absent skulduggery, that is.)

Well, actually you're right. It has nothing to do with it. I was more
thinking about hiding constructors and using abstract methods to force
initialization but it's irrelevant.

No, because I don't trust you. I've written my class, and
you're extending it, and I have no idea whether you know enough
about my class' internals to be able to duplicate them in your
code. (In fact, I've used an obfuscator on my class' byte code
specifically to conceal those internals from you

I don't need to know your internals or duplicate anything I just want to
change the arguments before calling your constructor. Your own example
with prime values shows it.

If I want to do that I need some tricks like separate init methods,
static methods etc..


No, thanks, Pitch. I'm too egotistical about my own code
to allow you to inject yours into the middle of it and then get
me to take the blame.

I suggest you check the arguments and use the InvalidArgumentException.
:)
 
E

Eric Sosman

esosman@ieee-dot- said:
[...]
Why is proper construction sequence so important? Why not just leave it
to access modifiers? Wouldn't that be more straightforward than having
silly rules like "super() must be the first line"??

1: So a class can establish its invariants, and not worry
about a subclass messing them up. (1a: So a subclass can rely
on its superclass to operate as advertised, without the subclass
needing to take on the responsibility for correct operation.)

If subclass messed them up it is the same thing as the caller messed
them up. That's why we do input validation.

How can the superclass' constructor validate its inputs
if the subclass has somehow substituted its own code so the
superclass' constructor never even runs?
I don't need to know your internals or duplicate anything I just want to
change the arguments before calling your constructor. Your own example
with prime values shows it.

If I want to do that I need some tricks like separate init methods,
static methods etc..

... and those "tricks" are available to you. What's the
problem?
I suggest you check the arguments and use the InvalidArgumentException.
:)

Yes, I see the smiley, but even so I don't think you Get It.
Here's a toy class:

class Toy {
private final ToyBox box;
Toy(ToyBox whereItBelongs) {
box = whereItBelongs);
}
void takeOutAndPlayWith() {
box.remove(this);
}
void putAwayAndSitDownForSupper() {
box.insert(this);
}
}

Suppose you extend this with an ElectronicToy class (with
additional methods for replacing batteries and such), and you
somehow instantiate an ElectronicToy without running Toy's
constructor. Your ElectronicToy "is a" (or "is supposed to
be a") Toy, so you ought to be able to takeOutAndPlayWith()
it -- except that the `box' reference has never been set up,
and there's a NullPointerException.

Now, how do you propose that takeOutAndPlayWith() should
deal with this situation? I suppose you could do

void takeOutAndPlayWith() {
if (box == null)
throw new IllegalStateException();
box.remove(this);
}

.... but has changing NPE to ISE improved anything? The kid
with the toys gets an exception, and a stack trace fingering
my code (not yours, although it's yours that's at fault), and
just between you'n me, Pitch, I find petulant children tiresome.

And that's my last word on the matter, because I find
petulant children tiresome.
 
P

Pitch

Not exactly. It's more like there has to be an object before you can call
methods on it. (The area where I was wrong.) There has to be an object
before you can do anything at all to it, really.

But why there isn't? Why the VM just doesn't allocate memory, clean it
up and make a reference to "this"? (I address this at the end, too.)
That's just the way Java is designed. There are tradeoffs to construction
parent-first vs. subclass-first.

Which are?

Which languages?

Delphi (Pascal), PHP

As for overriding any other non-private method, there is a difference between
the errors that occur when an object is not constructed yet vs. once it's
completely built.

What difference?

Several have answered
you to explain why it's not silly. That you call it that now, after having
read those replies, means that you are being obstinate.

You all say it's because base class must initialize its members but I
don't see what is so special about it.

- If you override a method and want the base class to perform its tasks,
you must call the apropriate base method.
- If you write a constructor and want the base class to perform its
initialization tasks, you must call the apropriate base constructor.

Simple as that, only one rule, no "first-line" exceptions!
Allowing code prior to superclass construction, or this-class
construction for that matter, would complicate matters horribly.

How? Btw, it can happen.

I really don't think that would be wise.

What do you mean by "a call, and not a syntax issue"?

Syntax is a set of rules about a text structure.
super() resembles more like a method call than a syntax-construct.
In fact, the issue of construction order is neither, whatever you might mean
by that. It's a matter of having an object on which to act.

And now for the final part...

You have all said that you need to create an object fully before using
it. Ok, this is one of the main principles of the OOP and this rule of
automatic base constructor invocation tries to conform to it.

But it has one limitation. It guarantees full construction only if the
members are initialized as constants or with private methods.

If you use protected methods there is a possibility that subclass will
change its behaviour thus changing the construction process. You will
end up with having base class using subclass' methods and members!

So what's the difference in allowing the constructor to be called at a
different point?

Another point is made in this article about .NET:
http://stackoverflow.com/questions/516844/1-good-reason-why-chained-
constructors-are-called-first

tinyurl:
http://tinyurl.com/afe6at

In short: .NET imposes this limitation in C#, J# and C++.NET, but does
not in other .NET languages (VB.NET, Delphi.NET...)! This is probably
because of compatibility reasons but it proves that the limitation is
not needed at all.
 
P

Pitch

esosman@ieee-dot- said:
How can the superclass' constructor validate its inputs
if the subclass has somehow substituted its own code so the
superclass' constructor never even runs?


True. Actually this is the same problem as passing invalid arguments.
The caller must be carefull, and yes, the caller is to blame.

Yes, I see the smiley, but even so I don't think you Get It.
Here's a toy class:

class Toy {
private final ToyBox box;
Toy(ToyBox whereItBelongs) {
box = whereItBelongs);
}

Well, if I pass here null you'll still get an error. :(
So throwing ISE here or throwing NPE later is more or less the same.
 
T

Tom Anderson

Why, so can I, or so can any man; But will they overflow when you do add
them?

My dear fellow, i have an investment scheme that is literally banking on
it!

Longs might be a better choice for general currency purposes - they'd
handle up to 92 petapounds on a penny basis, and i'd feel fairly confident
that no actual currency amount would exceed that. A programming language
which handles integer overflow sensibly (by throwing an exception) would
be another.

tom
 
A

Andreas Leitgeb

Arne Vajhøj said:
+ and - is a bit easier, but *, / and IO becomes
harder.

Multipliation with a "scalar" value isn't harder, and I haven't
yet had a need to multiply currency-values with other currency-
values. £·€, €²,£³ ?-)

about IO: well, yes, you gotta apply the scaling first.
 
A

Arne Vajhøj

Multipliation with a "scalar" value isn't harder, and I haven't
yet had a need to multiply currency-values with other currency-
values. £·€, €²,£³ ?-)

That is not very likely.

But some may multiply with exchange rates or interest rates.
about IO: well, yes, you gotta apply the scaling first.

Yep.

Arne
 

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,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top