8

It is common in Java classes to have lots of getter and setter methods, one each for every data model class variable. I realize that many IDEs will create these for you, but I'm trying to avoid this clutter and not have all these methods in my classes. So, is there any way to access a variable in a read only fashion outside the class (as if it were public final), while retaining write access inside the class or subclass exclusively (as if it were private or protected).

The only pseudo-solution I've come up with is a base class (or interface with default methods) that has a get(String variableName) method which then gets the fields of the class via reflection and returns the appropriate one. The downside is that for that to work, the variables have to be public, so only by convention does it meet my requirements (in that in the extending/implementing class that has the variables I want to access, I only call the get method from outside the class, and don't implement a set method). The main thing I don't like about this is that if a variable name changes, callers of the get methods will not cause compiler errors, since the variable name is just a hardcoded String.

Anyone have a better idea?

Razib
  • 10,965
  • 11
  • 53
  • 80
overcast75
  • 95
  • 1
  • 5
  • 7
    Yes. I have a better idea - *please don't do this*. *Reflection* is terribly slow. And by not having setters / getters, you break *encapsulation* as well as *abstraction*. And if you use frameworks like *Spring*, you will need setters. – TheLostMind Mar 19 '15 at 06:55
  • 3
    You should read once `Effective java by Joshua Bloch`. – Prashant Mar 19 '15 at 07:01
  • If you want to avoid clutter then don't write getters and setters unless you actually need them. – Ceiling Gecko Mar 19 '15 at 07:08
  • Clutter from loads of getters is difficult to avoid. You don't need many setters though as you should make your classes immutable whenever possible. – Paul Boddington Mar 19 '15 at 07:18
  • I recommend Groovy. I use it almost exclusively for data objects specifically for this reason. – chrylis -cautiouslyoptimistic- Mar 19 '15 at 07:21
  • @TheLostMind Reflection is not that slow; most Java frameworks use it exhaustively. An you don't necessarily need setters in Spring; you can also use constructor injection or autowiring. – Random42 Mar 19 '15 at 07:39
  • @m3th0dman - Ya I should have used *might* instead of *will* in case of Spring :).. Most java frameworks use reflection exhaustively, because there is no other option. If there was a better way, believe me they would have done that. I see a fundamental flaw in this approach - it breaks basic OOPs principles. – TheLostMind Mar 19 '15 at 08:10
  • @TheLostMind For example reflection can be used to dynamically call public methods, or to dynamically insantiate a public class; there is not break of encapsulation here. – Random42 Mar 19 '15 at 08:31
  • @m3th0dman - Reflection can be used to break *immutability* of `String` and *wrapper classes*, bits that not my point. :). I am merely pointing out that the OP might get into other design issues with this approach. – TheLostMind Mar 19 '15 at 08:39
  • @TheLostMind I understand the problem, but you can break encapsulation even without reflection if you want to do that. But probably the biggest drawback of reflection is the complicated code it yields. – Random42 Mar 19 '15 at 08:41
  • @m3th0dman - Yes. I agree :) – TheLostMind Mar 19 '15 at 08:48

3 Answers3

5

Yes - try to design your classes so you don't have getters and setters at all. Typically it's a bad design to have getters and setters on all of your fields because it breaks encapsulation. An exception is the case of Java Beans (where you have a model class/DTO or some class that's mapped to XML/JSON); here you should not mind them because setters and getters are the only methods.

In classes that have logic, inject your dependencies via constructor or directly if you use Spring/CDI and you like it. This is more safe because you won't have objects in inconsistent states; like for example you create an object but forget to call a setter -> NullPointerException. But by using constructors, you avoid the case of forgetting to call the setters.

Of course there might be exceptions, like when setting some optional fields when you don't want all the dependencies in the constructor all the time. This however can be solved with overloading constructors or if the case is more complex the problem can be solved in a more elegant way by using the builder pattern.

See a great article on this: http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html

Random42
  • 8,989
  • 6
  • 55
  • 86
3

You may use lombok - to manually avoid getter and setter method. But it create by itself.

The using of lombok significantly reduces a lot number of code. I found it pretty fine and easy to use. But here you may find some pros and cons of using lombok here.

Hope it will help.
Thanks a lot.

Community
  • 1
  • 1
Razib
  • 10,965
  • 11
  • 53
  • 80
1

Java FX introduced something similar to what you want: ReadOnlyProperty

Might not be exactly what you are looking for, though. In general, I don't think exposing a variable is a good idea.

Juan Lhc
  • 327
  • 3
  • 11
  • Or use classes implementing ``WritableValue`` such as ``BooleanProperty``, ``LongProperty``, ...: http://docs.oracle.com/javafx/2/api/javafx/beans/value/WritableValue.html – nrainer Mar 19 '15 at 07:19