I am a Java Developer working in Sydney. I am eager to learn new technologies, new frameworks, new languages. Thibault has posted 8 posts at DZone. You can read more from them at their website. View Full User Profile

Java SE 11: Moving Java Forward – Part 2

07.26.2012
| 5123 views |
  • submit to reddit

This series of articles presents how, in my opinion, the java language should evolve and therefore remain a top-choice language. It also presents some features, sometimes already existing in another language, that I love but cannot (or should never) be part of Java for reasons I will explain. I would really love to transform some of those ideas into JSRs one day.

Accessing fields of an object through a transparent accessor is definitely the feature I miss most in Java.

What is it?

In Java, we used getters and setters that gave us access to a property of an object. I will not speak of the benefits of having getters and setters instead of having public fields—I assume you are aware of that. In other languages (C#, AS3, ...), you can declare explicitly the getter and setter of a property and use them as if you were using a public property. My favorite syntax is the one ActionScript3, as shown below:
//Object Declaration
public class MyObject {
       private var _myProperty:String;

       public function get myProperty():String {
                return _myProperty;
       }

       public function set myProperty(value:String):void {
              _myProperty = value;
       }

       public function get firstLetter():String {
               return _myProperty.substr(0,1);
       }
}

//Usage
var o:MyObject = new MyObject();
o.myProperty = "A value"; //Set the property using the setter
trace(o.myProperty); //Print the value return by the getter
trace(o.firstLetter); //Print 'A'

The Java syntax suggestion

Since I consider the ActionScript 3 syntax very convenient, I think that the Java syntax should be very similar. It would require the addition of new modifiers : get and set.
public class MyObject
{

    private String _name;

    public get String name() {
        return name;
    }

    public set void name(String name) {
        this.name = name;
    }
}

//Usage
MyObject o = new MyObject();
o.name = "My name";
System.out.println("print entity : " + o.name);

Benefits

  • Using an accessor is transparent. The encapsulation is made implicitly. The caller does not know if it is calling a public variable or an accessor.
  • Better OO style programming: From an external class point of vue, an object now really has public methods and properties, while before it only had public methods.
  • Refactoring the code to change all direct accesses to the fields of the object is a piece of cake—you just have to change the class concerned, not all read/write calls.
  • No need anymore to have the JavaBean conventions on getter and setter. Some libraries relied on the fact that accessors of myProperty are called [get|is|set]MyProperty. Now, instead of the accesors being defined by convention, they're defined by contract. We can have a method on the class Class that retrieves the accessor (getGetters(), getSetters()). Once again, this is a big OOP enhancement.

Drawbacks

  • One requirement would be to change the naming convention of the object fields since the method and the property could have the same name. Undoubtedly the JVM could allow the property and method to have the same name, but that is more of a readability issue.

Implementation and Issues

Implementing this feature would require the addition of two new keywords (get and set) to the Java language. That is a bad thing for the retro-compatibility, but that is not a big problem. It would need to use the "-source"  command-line option as it has been done before when the assert keyword has been added in Java 1.4. This change would also require modification of the JVM specification, and the Java compiler, to add the two new modifiers. Those two new modifiers are needed in the class file in order to identify, using the reflection, the getters and setters of a class.

Conclusion

I believe that this feature would be an awesome improvement of the Java language. As all major improvements go, however, that would require a lot of work. If one day I'm ready to submit a JSR, it will definitely be this one!
Published at DZone with permission of its author, Thibault Delor.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

A Vy replied on Thu, 2012/07/26 - 10:44am

Setters are a bad thing, anything that makes them easier for specific syntax for them is just rediculous.

Balint Persics replied on Thu, 2012/07/26 - 12:36pm

" Better OO style programming: From an external class point of vue, an object now really has public methods and properties, while before it only had public methods. "

I disagree with this. OO-style programming has the idea, that we send messages between objects. Our program consists of separate objects passing messages to each other. There shouldn't be any properties out there, it is a legacy of the past: we think about objects as "enhanced" data structures. But in the real OOP sense, objects acts like services: you send in a message and you export your interface for incoming messages. That's it. Objects are not "clever" structs. And of course, what follows from this POV is that anemic domain models are bad.

Jonathan Fisher replied on Thu, 2012/07/26 - 1:41pm in response to: Balint Persics

I agree with Balint... Javabeans and Getters/Setters has drilled a producerual style of programming into Java. Real OO programming means an object has behaviors that do things, with functions to mutate an object's internal state. Instead, Javabeans turns Objects into "smarter structs" (well said!)

Nevertheless... We're already here. I think this idea could use a little work, but It's definitely worth a look at.

Earnest Dyke replied on Thu, 2012/07/26 - 2:00pm

Your suggested syntax is intriguing but I would rather see a more simplified syntax, for instance:

 

/*
 * Only generate GETTER
 */
private read String myField1;


/*
 * Generate both GETTER and SETTER
 */
private readwrite String myField2;

/*
 * Generate only SETTER
 */
private write String myField3; 

 Just MHO! 

 Earnie! 

Balint Persics replied on Thu, 2012/07/26 - 4:15pm in response to: Earnest Dyke

Thats bad. They should be methods, think about PropertyChangeListeners, class invariants and such.

Balint Persics replied on Thu, 2012/07/26 - 4:38pm in response to: Jonathan Fisher

That's right. JavaBeans are the best example of standardizing bad habits for a large number of developers. Without explaining what an object really is, introducing JavaBeans, simple accessors and mutators creates a false illusion of what OOP is.

In the real sense of OOP, an object should never expose any of its internal state to the outside world, even if some method calls are invalid in some state (for example you shoul not call getHeight() on a GUI widget without having its position and size computed by the layout).  Every method call should be allowed and every method call is expected to throw an IllegalStateException and the client is expected handle it. Consider a web server which need to be queried whether it can handle a request before actually making the request. And after all that preparation, you must be prepared for any errors anyway...wouldn't it be against common sense?

There should be no code like this:

if(AnObject.getInternalState() == 5) {
    AnOBject.DoSomeThing(); 
} else {
    AnObject.DoSomeThinElse(); 

The object should handle the request according to its internal state or throw an IllegalStateException if the request (even if it is set up correctly) cannot be satisfied or an IllegalArgumentException if the request is malformed. By request I mean the arguments of the method for which the message has been sent to.

Code that works like the above usually has a large Feature Envy (see: http://sourcemaking.com/refactoring/feature-envy), it is interested in the internal state of an other object more than its own state. 

 

Clemens Eisserer replied on Fri, 2012/07/27 - 1:25am

Yet another idea for a feature with no real value in it.
Things like that usually make the language more complex.

Misja Alma replied on Fri, 2012/07/27 - 6:39am

Why not just: 

@Bean  // This will generate getters and setters
public class MyBean {
  private int myIntProperty;
  private String myStringProperty;
}

 

Balint Persics replied on Fri, 2012/07/27 - 10:22am in response to: Misja Alma

You may check Project Lombok, which has a similar syntax (the annotation is @Data, not @Bean).

Tomáš Záluský replied on Sat, 2012/07/28 - 5:41pm

At least: adding new such keywords as "get", "set" would IMHO break a lot of existing code with carelessly named sets, for example Set set = new HashSet();, unless the keywords were context-dependent.

Balint Persics replied on Mon, 2012/07/30 - 2:25am in response to: Tomáš Záluský

Good point. I did not consider that.

Arash Shahkar replied on Mon, 2012/08/20 - 4:07am

Are you really fixing a problem here? Has the traditional approach of getters/setters ever caused you a problem in real world? Your solution suggests adding two keywords to the language without really adding a significant missing feature or fixing a major problem. IMO, a language which has to remain a top-choice for a long time should remain simple in the syntax.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.