Public defender methods and static inner classes in interfaces?

Reinier Zwitserloot reinier at zwitserloot.com
Thu Sep 16 22:08:40 PDT 2010


So?

If the structure of the language syntax suggests that some job should be
done in a certain way, but that way is known by experts to lead to hard to
maintain code, the language screwed up.

On the other hand, if the structure of the language syntax explicitly leads
you away from a known problematic path but there's a hacky way to do it,
there's no problem. A flexible language also means you can shoot your leg
off if you willingly hack your way around safety features. There's also
nothing stopping i.e. lombok from letting you declare something like:

Dynamic foo = whatever();
foo.bar(); //gets rewritten to
foo.getClass().getDeclaredMethod("bar").invoke(foo) with appropriate
exception catching

But we haven't gone there, and frankly nobody's asked that we do, either. I
see no problem with the existence of reflection, even though you can indeed
use it to get around the type system.

When you're programming an extension method and you hack state into it using
a weak identity hash map, I'm fairly sure the language has done all it can
to tell you what you're doing is a bad idea. Why would you want to outright
stop a programmer from shooting their leg off? There are always times when
the weird, hacky solution is the better one if you know what you're doing.

Speaking as one of the two folks with veto rights on whatever goes into
Lombok, I'm not currently planning on ever allowing a boilerplate buster
annotation to add the ability to have stateful extension methods. So that's
one framework down :P

 --Reinier Zwitserloot



On Tue, Sep 14, 2010 at 5:46 AM, Collin Fagan <collin.fagan at gmail.com>wrote:

> I keep reading these proposals and I keep reading that public defender
> methods have "no state" and yet I can't bring myself to believe it. They
> may
> be intended to have "no state" but that really doesn't mean people aren't
> going to try.. and succeed... to make this multiple inheritance or traits
> or
> mix-ins.
>
> Example:
>
> public extension void setExtendedValue(Object parameter)
>       default Example1.setExtendedValue;
>
> class Example1 ...
>
> private static IdentityHashMap<Object, Object> extendedValues = new
> IdentityHashMap<Object, Object>();
>
> public static void setExtendedValue(Object extendedInstance, Object value){
>    extendedValues.put(extendedInstance, value);
> }
>
> public static Object getExtendedValue(Object extendedInstance){
>    return extendedValues.get(extendedInstance);
> }
>
> *POOF* inheritance of state.
>
> I can see entire "frameworks" and/or Spring/Guice/Lombok/Commons
> modules/extensions purposefully built to make this easy and manage the
> object allocation for you.
>
> *Don't want to have to write all that boiler plate code? Our framework will
> allow you to "inject" all the functionality you want! Just use
> Injectortron!
> *
>
> Have you ever needed to modify a final variable in an inner class? Have you
> even used the single element array hack? It's all over the web, it's well
> known and people use it when that the whole final thing becomes
> inconvenient. I have a bad feeling that we have the same situation here. If
> you provide this feature someone else is going to "fill the gap" with their
> vision of what this functionality *should *have been.
>
> .. and I don't have a solution. I tried, but I'm just not smart enough to
> compensate for the erasure of generics. I'm only smart enough to abuse
> defender methods.
>
> On Mon, Sep 13, 2010 at 9:03 PM, Jim Mayer <jim at pentastich.org> wrote:
>
> > Hi Dave,
> >
> > The "defender method" idea seems useful to support extension of existing
> > interfaces, but I'm worried that the ability to put algorithms into
> > interfaces will blur the distinction between interfaces and classes.  One
> > of
> > the problems with C++ is that there are so many ways of doing the same
> > thing
> > that the conventions around the use of a feature become more complicated
> > than the feature itself.
> >
> > Currently interfaces have a well defined purpose: they specify a contract
> > without an implementation.  That's a simple concept to get across and the
> > language enforces it.  Once we allow algorithms to be implemented in
> > interfaces the picture becomes less clear, especially for inexperienced
> > developers.
> >
> > On the other hand, Java interfaces can already contain constants and it's
> > hard to argue why, since we're adding lamba like expressions to Java, we
> > shouldn't just treat the default methods as constant values.  In fact, I
> > think the cleanest proposal is to let interface method definitions have
> > bodies... that's the most familiar syntax of all.  I'm just worried about
> > unintended consequences... interfaces were introduced, I assume, because
> of
> > the widespread concern about multiple inheritance.  Defender methods
> raise
> > the same issues as multiple inheritance, and the rules for resolving
> > ambiguity are (necessarily) non-local in effect.  Adding a new method
> with
> > a
> > "defender" seems like an innocent change to an interface, but the
> non-local
> > nature of the conflict resolution algorithms means that it will be easy
> to
> > break existing code or, perhaps worse, produce code that yields
> unexpected
> > results.
> >
> > Anyway, that's why I would prefer something like the proposal in (
> > http://cr.openjdk.java.net/~darcy/DefenderMethods.pdf<
> http://cr.openjdk.java.net/%7Edarcy/DefenderMethods.pdf>).
> >  It's ugly, and that
> > seems appropriate here. :-)
> >
> > -- Jim
> >
> > On Wed, Sep 8, 2010 at 1:27 PM, David Walend <david at walend.net> wrote:
> >
> > > On Sep 8, 2010, at 8:59 AM, Jim Mayer wrote:
> > >
> > >  One problem with the suggestion below (that 'private' be allowed on
> > >> classes inside interfaces) is that it won't play nicely with unit
> > testing
> > >> frameworks such as JUnit.  JUnit conventions rely fairly heavily on
> > >> 'package' protection, and a 'private' class inside an interface would
> be
> > >> difficult to test.
> > >>
> > >> This may, or may not, matter in practice, but I hate to see us do
> > anything
> > >> that makes unit testing harder.
> > >>
> > >> My own preference, at this point, would be to keep implementation out
> of
> > >> interfaces as much as possible, provide implementations in a separate
> > file,
> > >> and hope that the defender method feature isn't abused too much.
> > >>
> > > <snip>
> > >
> > > Jim, this is what I'm curious about. What do you see as abuse (vs. wise
> > > use)?
> > >
> > > We can take this off list if no one else is interested. It's sure to
> > stray
> > > into syntax.
> > >
> > > Thanks,
> > >
> > > Dave
> > >
> > >
> > >
> >
> >
>
>


More information about the lambda-dev mailing list