From: Andreas Leitgeb on
Tom Anderson <twic(a)urchin.earth.li> wrote:
>> This whole topic is inspired by dynamic loading of classes.
> This problem was solved in the golden age of the Patternists. The solution
> is that you don't load Entertainers, you load EntertainerAgencies.

Oh, nice! Yet another extra indirection!
Wasn't there some "computer law" that said, that any problem can be
addressed (but not necessarily solved) by adding another level of
indirection?

> public interface EntertainerAgency {
> public Entertainer hire();
> }

In that case, I'd *demand* EntertainerAgencies to offer a no-args c'tor,
until Eric comes up with ComedianAgency that just wants a default joke
for the Comedians it has under contract itself.

> The question of some putative Entertainer constructor goes away. You do
> have the question of the EntertainerAgency constructor, but this is much
> less pressing. If it really worries you, use a EntertainerAgencyFactory.

And then an EntertainerAgencyMetaFactory for that, just in case...

> Before you ask, yes, it's factories all the way down. Until you reach the
> turtles.

What? They don't yet have a TurtleFactory?
Someone instantly go complain to T.P.!

From: Arved Sandstrom on
Andreas Leitgeb wrote:
[ SNIP ]

> This whole topic is inspired by dynamic loading of classes. Otherwise, there
> wouldn't really be any use for dictating constructors at all. Dynamic loading
> of classes seems to me of increasing importance with all those AppServers,
> J2EE, ... Demanding the default-constructor (or even with a specific set
> of arguments) for those classes imposes no new restriction, just formalizes
> the restrictions that were already imposed by documentation and use.
>
> PS: In recent threads I spoke up against restrictions, and now I promote them?
> It's different types of restrictions, of course: an extra method or c'tor
> is easily added as a dummy, but an idly added "final" is much harder to come
> by, if deemed improper, later.

This is a major use-case, yes. JPA EJB3 entities and JSF managed beans,
to take 2 examples, are user-defined classes that require no-args ctors.
It's not that common to explicitly construct JSF managed beans, so no
real issue there, but I already mentioned the usefulness of enforcing
the presence of no-args ctors for JPA entities.

I don't see this exact use-case as being _highly_ compelling, but an
argument can be made that a mechanism for enforcing no-args ctors where
they are required is nonetheless mildly useful in the context of dotting
all the i's and crossing all the t's.

I agree with you that the annotations approach (which works quite well
for any kind of ctor, not just the no-args one) would be nicer if common
annotations were a bit more "standardized." Java 6 has been out for a
while and so I'm surprised (a bit) that this evidently hasn't happened
(like an Apache Commons Annotations project or something, although there
are 3rd party libraries that supply various sets of useful or
semi-useful compile-time annotations.) And there're still plenty of
misconceptions out there; I ran across this quote:

"Unless you are writing your own Java compiler, it is not possible to
create your own useful compile-time annotations."

in one article. This perception is obviously preventing some people from
writing or even looking for annotations of a certain sort.

If useful annotations were to be truly standardized then I guess they'd
end up in JSR-250, and therefore probably in javax.annotation.*.

AHS
From: Andreas Leitgeb on
Arved Sandstrom <dcest61(a)hotmail.com> wrote:
> This is a major use-case, yes. JPA EJB3 entities and JSF managed beans,
> to take 2 examples, are user-defined classes that require no-args ctors.
> It's not that common to explicitly construct JSF managed beans, so no
> real issue there, but I already mentioned the usefulness of enforcing
> the presence of no-args ctors for JPA entities.
Yes.

> I don't see this exact use-case as being _highly_ compelling, but an
> argument can be made that a mechanism for enforcing no-args ctors where
> they are required is nonetheless mildly useful in the context of dotting
> all the i's and crossing all the t's.

I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t",
but rather an "l" (well, depending on the font, perhaps). With that,
the question of enforcing c'tors is even less "compelling" than making a
"t" a real "t".

It's not about achieving new possibilities, but only about shifting the
diagnosis of some programming error from runtime to compiletime - namely
to the time of compiling certain derived classes whose primary use is
eventually being Class.forName(...).getInstance(...)'ed.

> I agree with you that the annotations approach (which works quite well
> for any kind of ctor, not just the no-args one) would be nicer if common
> annotations were a bit more "standardized." ...

Amen :-) If those annotations were already standard, the discussion
about other (new) mechanisms to enforce c'tors would be moot.

From: Andreas Leitgeb on
Tomas Mikula <tomas.mikula(a)gmail.com> wrote:
>> > The idea here was to automate the reflection.
>> Sorry, that is a non-starter.

>> If you don't know the class at compiletime, then neither does the
>> compiler, so there's nothing the compiler could possibly do for you
>> beyond what it already does, namely write bytecode to have the JVM
>> check it all at runtime.

> In my original post I noted that the use of Class's newly introduced
> method
> <T> Implementation<T> asImplementationOf(Class<T> clazz);
> would have the restriction that the type T is known at compile time.

The syntax you use suggests, that the result of that function would be
some object (yes, an instance, a bit like the Class-Objects), that offers
methods to call the dynamically loaded class' static methods...

class MyBase {
static abstract void foo();
}
class MyImpl extends MyBase {
static void foo() { System.out.println("Called me"); }
}
use:
Implementation<MyBase> impl = Class.forName("MyImpl").
asImplementationOf(MyBase.class);
impl.foo(); // prints "Called me".
Implementation<MyBase> implFail = Class.forName("MyBase").
asImplementationOf(MyBase.class);
// the preceding line throws error, because MyBase doesn't
// *implement* the abstract method foo().

Is that your intention?
If yes, please read on; If no, the rest of my posting may be moot.

> In this case, the compiler can generate the bytecode to check if the
> 'this' class implements T.

I think, that whenever such a hierarchy of static methods is wanted,
an alternative solution with virtual (i.e. non-static) methods is
easily available with (if at all) only small cosmetic "up to taste"
drawbacks.

> - it requires to get an unnecessary instance (not so bad yet);
> - getting this instance requires reflection
Reflection already starts at Class.forName(...) and if I understood
correctly, you didn't intend to replace that call.

> - using reflection for getting an instance requires conventions
> which cannot be checked at runtime (such as the presence of
> some particular (e.g. no-arg) constructor)

Of course it *can* be checked *at runtime*! See Class.newInstance().
If that throws an Exception, then there obviously was some problem in
the attempt to call the no-args constructor of the class.
This simple line:
MyBase mb = (MyBase)Class.forName("MyImpl").newInstance();
already checks *at runtime*, that
- the named class is loadable
- the named class has a no-args c'tor
- the no-args c'tor succeeded (did not throw an exception itself)
- the thusly construed instance is castable to "MyBase".

> Furthermore, if I forget to override pseudoStatic() or realStatic() in
> a subclass, I will get the realStatic() from superclass, which is not
> what I want.

If you forgot to override pseudoStatic(), then the derived class will not
even compile (assuming it is not declared as abstract, itself). For
non-static methods, all those mechanisms are already well worked out.

Overriding realStatic() is not an issue, as you just wouldn't define
it in the base class, and so the call to realStatic() in the overridden
pseudoStatic() would fail at compile time, until you either add a
realStatic() method, or just did something else in the (enforcedly
existing) implementation of pseudoStatic().

>> I don't think, that calling static methods on dynamically
>> named classes is worth such deep changes as you seem to have in mind
>> for this task.
> The good thing about it is that the changes are not real changes, just
> extensions. So far I think they are all backward compatible with
> current specification. No old code would be broken if these extensions
> are introduced.

I do not even doubt that.
It's just that these extensions add much too much fuss and doesn't
seem to gain a substantial advantage in return.

From: Andreas Leitgeb on
(this is a supercede to correct my mistake: getInstance -> newInstance )

Arved Sandstrom <dcest61(a)hotmail.com> wrote:
> This is a major use-case, yes. JPA EJB3 entities and JSF managed beans,
> to take 2 examples, are user-defined classes that require no-args ctors.
> It's not that common to explicitly construct JSF managed beans, so no
> real issue there, but I already mentioned the usefulness of enforcing
> the presence of no-args ctors for JPA entities.
Yes.

> I don't see this exact use-case as being _highly_ compelling, but an
> argument can be made that a mechanism for enforcing no-args ctors where
> they are required is nonetheless mildly useful in the context of dotting
> all the i's and crossing all the t's.

I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t",
but rather an "l" (well, depending on the font, perhaps). With that,
the question of enforcing c'tors is even less "compelling" than making a
"t" a real "t".

It's not about achieving new possibilities, but only about shifting the
diagnosis of some programming error from runtime to compiletime - namely
to the time of compiling certain derived classes whose primary use is
eventually being Class.forName(...).newInstance(...)'ed.

> I agree with you that the annotations approach (which works quite well
> for any kind of ctor, not just the no-args one) would be nicer if common
> annotations were a bit more "standardized." ...

Amen :-) If those annotations were already standard, the discussion
about other (new) mechanisms to enforce c'tors would be moot.