My thoughts on the Java 7 property debate

15

There’s been a lot of good discussion and debate recently about the idea of first class support for properties and events in Java 7 (possibilities include a new property keyword or a new -> syntax or even using annotations). I’m only mildly convinced that having properties and events in the language as first-class entities (presumably with the intention to support component-oriented programming) is worth doing. I’m particularly turned off by the -> syntax. Using annotations for this doesn’t seem worth the effort. Some more links can be found here: Danny Coward presentation that started this discussion, Rémi Forax, Stephen Colebourne, Kirk.

There are two places in Java that we have what I’ve heard Stuart Halloway call non-hygienic syntax. [The reference here is to hygienic macros in Scheme to basically mean macros that when expanded can’t break the meaning of the code they are used in.] Stu uses this term to describe syntax that doesn’t let the implementer of a component change their implementation without breaking the user of the component.

Example 1: Object Construction – Say I write an object called RockStar and you new one up: RockStar singer = new RockStar("Mick Jagger"); But then later on I create a new class called AgingRockStar and I really wish that I could return give my user an instance of AgingRockStar instead of RockStar. But, of course, I can’t unless my component’s caller changes his code. So, this is non-hygienic because a change on my side of the component requires a change to all of the callers of my component.

The standard way to avoid this issue is to use the factory method pattern (or abstract factory, etc). If you have a factory method that returns an interface or base class, the factory method is free to switch from returning RockStar to returning AgingRockStar or DeadRockStar or whatever else it wants in response to inputs.

Example 2: Field Access – The other place you can see something like this is with Java fields (or in a stronger form, properties). If I create a class with a public field, I can set the value directly:

public class Payment { 
    public int dollars; 
}

Payment wasteCollectionBill = new Payment();  
wasteCollectionBill.dollars = 20;

But say that your model becomes more complicated and you need to take into account that some Payments have kickbacks (maybe the Sopranos collect your garbage, for example). In that case, you may need to change it around a bit:

public class Payment { 
    private int dollars;  
    public void setDollars(int dollars) {
        extractKickback(dollars);
        this.dollars = dollars;
    }
}

Payment wasteCollectionBill = new Payment();  
wasteCollectionBill.setDollars(20);

Notice that when you switch from using a field to a setter method, all calling code breaks and must be changed. Again, this is a non-hygienic syntax. This is such a pervasive problem that Java developers just code to the idiom that all class fields should be protected by getter/setter methods, which inevitably means more boilerplate code (which is so dumb your IDE can create it for you automatically).

I’m interested in the property proposal purely because it hints at a way to solve the issues in #2. If we were able to use a single syntax to mean either o.field or o.getField(), then we’re good. At that point, you can simply start with the field. Callers use the dot syntax and if you later decide a method is needed, then you can one without breaking those callers and they automatically redirected. This is also why I dislike the new -> operator suggestion. If we have to tell callers that this is happening, it ruins the whole point of doing it. I don’t see why they need to know or care whether they are accessing a field directly or going through a method. This class is a component with a data value and I want to get it.

Problem #1 is a little tougher I think. One way to cover this requirement (taken from other languages) is to allow an object constructor to return an object of a different class (but still type-compatible). This allows new to become a hygienic syntax as it can be much more flexible. I suspect that’d be quite a big change in both philosophy and semantics in Java, so I’m not holding my breath.

Comments

15 Responses to “My thoughts on the Java 7 property debate”
  1. I agree. Public fields should be redirected to the get or set method without the caller knowing what’s happening. If necessary for backwards compatibility, there could be an annotation to specify this behavior. This would (slightly) decrease the size of the caller’s code and remove the need to generate all of those useless getters and setters. How cool. Applications that rely heavily on POJOs would see a significant decrease in lines of code.

  2. Myron Alexander says:

    The way D handles properties would solve your problem:

    http://www.digitalmars.com/d/property.html

  3. Myron Alexander says:

    Forgot to add that the relevant section is under:

    Class and Struct Properties

  4. KIrk says:

    This is a very nice way of saying what I’ve said in my blog entry. I’m not familiar with D but from what I did see from looking at the link, this is *exactly* the kind of syntax that I’d *argue* against.

    The real issue from what I can see is; what happens when we get to the edge of a system. And by that I mean, what happens when we hit the glass, wire, database, or federate or otherwise distribute into another JVM. In every case we necessarily violate encapsulation or create a situation where our code can no longer be hygienic.

    In these situations,overloading “.” or adding “->” in the same sense that C# does would appear to make sense. However my sense is that this activity also merges API and implementation by convention.

    This get/set convention set by the JavaBeans specification and blindly followed by the vast majority of Java developers is something that I’ve never been quite able to get used to. Exposing state via get IMHO is to be avoided. Letting mutable state escape via set should also be avoided. Demeter both tolerates and demands this.

    It does so because we all need “friends” to help us get things done. We just want to make sure that only “enimies” can’t do harm.

    Kind regards,
    Kirk

  5. tvik says:

    This property stuff is nice but what about adding new parameters and throwing exceptions?

    When I have to extend my setDollars(…) method with a further parameter: e.g.: setDollars(int amount, Date rateDate)

    Or when I have to throw exception in certain cases?
    if(amount

  6. tvik says:

    End of my previous post:

    if(isInvalid(amount)) throw new InvalidAmountException();

    How can I change property code staying to be “higienic”?

  7. Alex says:

    Interesting point. This is the one of the issues with leaky abstractions. And maybe when you deal with all the real issues involved, this turns out to be too messy to be worth it. One option is to only allow RuntimeExceptions to be thrown from the getter/setter, although I can see how that would make some people unhappy.

  8. josh says:

    What I think is that you all miss the point here. I find many people acts like small children: “I do not like this getter and setter!!! Take it away from me!!”. Leave that getters and setters alone, PLEASE.
    The whole problem about “properties” is about data binding. I am developing Swing front-end application, with huge amount of data in JPA’s entity beans which are all filled up with really stupid getters and setters and this is __the least__ problem (IDE generates it, by th way:)

    The whole nightmare is with data binding. I am really waiting for a “property” to be an object (maybe something like java.lang.Property, so I can bind my bean with another bean or GUI widget and whenever I change anything on one side I want it change at the other side.
    Right now this is A NIGHTMARE. I am using some magic libraries which are intercepting calls to setters and fire property changes. When a property becomes an object, there will be no need for firing anything, and Java for desktop will become easy and powerful.
    My proposition is to add “->” which would create an object from a property, but not to add any other keywords or changing getters and setters.

  9. Alex says:

    Hey Josh, I think what you’re asking for is similar to JSR 295 (tentatively targeted at Java 7). There are a couple useful links on my Java 7 page.

  10. josh says:

    Hi Alex,
    I know they are working on JSR 295 (and 296 for Swing related enhancements) but I am worrying that these JSRs will add only new API for that, and I think there should be some help from the Java language itself. Right now there are few APIs for that, like excellent JGoodies Binding, but for such an API to work, you have to arm your beans’ setters with firePropertyChange stuff and add something that works like a “pointer” – for example: public static final String PROPERTY_NAME = “propertyName”. Thinking about solution for that is a good problem to consider I think.

    Introducing something like “->” would give us object representation for properties, so there will be no need to fire propertyChanges events and no need to add public static final Strings acting as a pointer for our properties.
    When few object could share one instance of property many problems will be resolved very easily. Of course I cannot imagine right now how could they implement such a new feature into Java in a way that would not break compatibility with legacy stuff, but I believe they can :)

  11. Darren Cruse says:

    Have thought for some time Java was overdue for some “syntactic sugar” around properties. I’ve recently been working with Objective-C which has an optional “@property” directive and dot syntax, yet otherwise it’s notion of properties as methods is much the same as javas under the covers.

    And I agree with your dislike of the “->” proposal for much the same reason (hopefully the outcome of this should simplify things for programmers not introduce something new they have to think about – i.e. “do I use the dot or the arrow here let me think hmmm).

    I guess the part I really wanted to comment on was that as I read your Field Access Example #2, I wondered if people would feel, as I do, that this has the static/dynamic language debate written all over it.

    i.e. I don’t know java bytecode, but I’m guessing it’s safe to assume that as the java compiler creates the bytecode behind your two versions of the client code using the Payment class, the dollars field access bytecode will differ greatly from the setDollars method invocation call.

    So in java the understanding of “.splat” is a compile time thing. For “.splat” to be an abstraction like you (and I) want, the java compilers would have to emit bytecode that try and understand what “splat” is *at runtime*, or else *calling* code is going to have to be recompiled whenever someone makes the kind of change you made to your Payment class in Example 2.

    So in a way, given that Java in my mind is a statically typed, performance focused language in the vein of C++, I could almost forgive the idea that this should properly wind up in the Groovy and JRuby kind of languages, and not Java.

    Because it seems a big change to think the compilers would be adding this kind of indirection for all the “.” references they find in the code, i.e. potentially a real performance drain given that the benefits might only apply in a small percentage of the time that “.” is used.

Trackbacks

Check out what others are saying about this post...
  1. […] Properties – I think something around properties would be cool, but I haven’t seen a properties proposal that I’m excited about yet. I think in this case, the devil is in the details. I concur with Charles that defining it on interfaces would be nice. So here’s my reason not to have properties (I’ll take my chances that Charles won’t kill me): no implementation/proposal exists that doesn’t suck in some way. And perhaps more importantly, maybe a non-sucky properties proposal is not possible. I don’t know. If the actual implementation added properties but made the whole language more complicated as a result, then I don’t think it would be worth it. […]

  2. […] Java 7 Published September 9th, 2007 Uncategorized Now that Java is open source and all that, everyone is up for adding new features to the language that Sun never got around to adding. Things like named arguments, closures, and properties are what interest me most. Unfortunately, I find myself disagreeing with most of what is being said. Most of the ideas start with a fairly simple and easily overcome problem, a fairly complex solution, then begin tacking on as many “It would be cool if…” or “… just like Ruby” ideas as possible. […]

  3. […] Now that Java is open source and all that, everyone is up for adding new features to the language that Sun never got around to adding. Things like named arguments, closures, and properties are what interest me most. Unfortunately, I find myself disagreeing with most of what is being said. Most of the ideas start with a fairly simple and easily overcome problem, a fairly complex solution, then begin tacking on as many “It would be cool if…” or “… just like Ruby” ideas as possible. […]

  4. […] More info: Closures, Properties, Chained invocation […]