
Signature
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
On Mar 8, 8:47 am, Christopher Benson-Manica
<a...@ukato.freeshell.org> wrote:
> Recently, it chanced that some code like this was written:
>
[quoted text clipped - 23 lines]
> C. Benson Manica | I *should* know what I'm talking about - if I
> cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
It seems a bit excessive to create a whole new object, just to call a
method on it. How about a static method?
public class Bar extends Foo {
// Foo has one constructor, taking a List<String> as an argument
public Bar(final Object... args) {
super( convert(args) );
}
private static List<String> convert(Object...args) {
final List<String> list = new LinkedList<String>();
// Transform args into String's and put them in the list
return list;
}
}
Tom Hawtin - 08 Mar 2007 18:40 GMT
> On Mar 8, 8:47 am, Christopher Benson-Manica
> <a...@ukato.freeshell.org> wrote:
[quoted text clipped - 8 lines]
> It seems a bit excessive to create a whole new object, just to call a
> method on it. How about a static method?
Or use a static creation method:
public class Bar extends Foo {
public static create(Object... args) {
List<String> list = new java.util.ArrayList<String>();
// LinkedList is almost always a bad idea.
// Use Arrays.asList if you want to be uber efficient.
...
}
private Bar(List<String> args) {
super(args);
}
...
Also Callable is defined to throw Exception.
Tom Hawtin
Christopher Benson-Manica - 08 Mar 2007 19:16 GMT
> It seems a bit excessive to create a whole new object, just to call a
> method on it. How about a static method?
Sounds good to me, that was the insight I was looking for. Thanks.

Signature
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
> Recently, it chanced that some code like this was written:
>
[quoted text clipped - 18 lines]
> idiom for accomplishing this goal, or is there a more elegant
> solution?
You do not show Foo but as Daniel said already, basically you are
invoking Foo(List<String> list). The situation would be different if
you did not invoked call() and just handed the Callable to Foo's
constructor. Having said that, yes, use a static method as Daniel
pointed out already.
Kind regards
robert
> Recently, it chanced that some code like this was written:
>
[quoted text clipped - 10 lines]
> }
> }
God help us -- that's /vile/ !
> The motivation is to transform Foo's constructor interface into
> something that is more convenient for Bar's clients. This strikes me
> as grievously hacky, but I also don't see another way to accomplish
> this aside from refactoring, which may not even be possible depending
> on where Foo comes from.
I'd use a static helper. Or, if that turned out to be impossible, take it as
a very strong indication that the design was a pile of crap and start again.
BTW, I question whether that idiom is really legal. Or, if it should turn out
to be within the letter of the JLS law, whether it /should/ be legal.
The problem is that it makes use of a reference to the object under
construction (using it to create the instance of the inner class) before the
superclass's constructor has been invoked. That is forbidden in every other
part of the Java design. It is OK, however foolish, to pass around references
to "this" after the superclass constructor has returned, but before your own
constructor is complete; but it is /not/ OK to do so before calling the
superclass constructor.
In fact I'm somewhat surprised that it passed verification in the JVM -- there
are strict rules about what you can do with a reference to a allocated-but-not
fully-initialised object, and until the call to the superclass constructor has
returned, "this" is in an illegal state.
-- chris
Christopher Benson-Manica - 08 Mar 2007 19:57 GMT
> God help us -- that's /vile/ !
Well, I wasn't a big fan either, although I did have to be a bit more
diplomatic about things :-) (Perhaps tellingly, a slight elaboration
on the code in question also exposed a flaw in IntelliJ's code
inspection - clearly it's at least uncommonly used enough that the bug
escaped notice until now!)
> The problem is that it makes use of a reference to the object under
> construction (using it to create the instance of the inner class) before the
> superclass's constructor has been invoked.
I'm still fuzzy on some of the things that lurk hidden from the eyes
of the casual programmer - but yes, now that you mention it, it's
obvious.
> In fact I'm somewhat surprised that it passed verification in the JVM -- there
> are strict rules about what you can do with a reference to a allocated-but-not
> fully-initialised object, and until the call to the superclass constructor has
> returned, "this" is in an illegal state.
It seems that the Java compiler is smart enough to determine when
you've clearly overstepped your bounds - say by accessing a field in
the subclass before the superclass constructor has been called - and
when you've merely committed stylistic seppuku.

Signature
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Tom Hawtin - 08 Mar 2007 20:10 GMT
> BTW, I question whether that idiom is really legal. Or, if it should turn out
> to be within the letter of the JLS law, whether it /should/ be legal.
It's certainly an area where the JLS and javac have been at odds in the
past. In this case, javac seems to consider the nested class to be in a
static context. At least that is consistent with the output of javap -c
on 1.6.0 u1 ea b03 (other builds may do something different).
Tom Hawtin
Chris Uppal - 08 Mar 2007 20:46 GMT
[me:]
> > BTW, I question whether that idiom is really legal. Or, if it should
> > turn out to be within the letter of the JLS law, whether it /should/ be
[quoted text clipped - 3 lines]
> past. In this case, javac seems to consider the nested class to be in a
> static context.
So it does ! Viler and viler...
(Though, to be honest, that does slightly reduce my distaste for the original
trick -- at least the code /is/ static, for all it doesn't look it.)
-- chris
Tom Hawtin - 09 Mar 2007 00:19 GMT
> So it does ! Viler and viler...
>
> (Though, to be honest, that does slightly reduce my distaste for the original
> trick -- at least the code /is/ static, for all it doesn't look it.)
The trick looks reasonable, until you realise it isn't doing quite what
you expected.
Anyway, I was looking for this bug in particular:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6226815
The example of an anonymous inner class within an inner class
constructor given in the JLS which isn't supposed to compile, does
(unless -target 1.4 or earlier is used, apparently).
Note the bug description says the code is from JLS2 (8.8.5.1) and the
bug is closed on that basis. However 8.8.7.1 (p245) of JLS3 has the same
code (the maintenance review has a mark against it, but doesn't appear
to have changed anything). I guess that bug should be reopened.
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#229267
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.7.1
If only JDKs had version number 0.1 (or 0.2) lower, nested classes could
have been a VM-level concept.
Tom Hawtin