So, I have willfully kept myself a Java n00b until recently, and my first real exposure brought about a minor shock: Java does not have C# style properties!
Ok, I can live with that. However, I can also swear that I have seen property getter/setter code in Java in one codebase, but I cannot remember where. How was that achieved? Is there a language extension for that? Is it related to NetBeans or something?
There is a "standard" pattern for getters and setters in Java, called Bean properties. Basically any method starting with get, taking no arguments and returning a value, is a property getter for a property named as the rest of the method name (with a lowercased start letter). Likewise set creates a setter of a void method with a single argument.
For example:
// Getter for "awesomeString"
public String getAwesomeString() {
return awesomeString;
}
// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
this.awesomeString = awesomeString;
}
Most Java IDEs will generate these methods for you if you ask them (in Eclipse it's as simple as moving the cursor to a field and hitting Ctrl-1, then selecting the option from the list).
For what it's worth, for readability you can actually use is and has in place of get for boolean-type properties too, as in:
public boolean isAwesome();
public boolean hasAwesomeStuff();
I am surprised that no one mentioned project lombok
Yes, currently there are no properties in java. There are some other missing features as well.
But luckily we have project lombok that is trying to improve the situation. It is also getting more and more popular every day.
So, if you're using lombok:
#Getter #Setter int awesomeInteger = 5;
This code is going to generate getAwesomeInteger and setAwesomeInteger as well. So it is quite similar to C# auto-implemented properties.
You can get more info about lombok getters and setters here.
You should definitely check out other features as well.
My favorites are:
val
NoArgsConstructor, RequiredArgsConstructor, AllArgsConstructor
Logs!
Lombok is well-integrated with IDEs, so it is going to show generated methods like if they existed (suggestions, class contents, go to declaration and refactoring).
The only problem with lombok is that other programmers might not know about it. You can always delombok the code but that is rather a workaround than a solution.
"Java Property Support" was proposed for Java 7, but did not make it into the language.
See http://tech.puredanger.com/java7#property for more links and info, if interested.
The bean convention is to write code like this:
private int foo;
public int getFoo() {
return foo;
}
public void setFoo(int newFoo) {
foo = newFoo;
}
In some of the other languages on the JVM, e.g., Groovy, you get overridable properties similar to C#, e.g.,
int foo
which is accessed with a simple .foo and leverages default getFoo and setFoo implementations that you can override as necessary.
public class Animal {
#Getter #Setter private String name;
#Getter #Setter private String gender;
#Getter #Setter private String species;
}
This is something like C# properties. It's http://projectlombok.org/
You may not need for "get" and "set" prefixes, to make it look more like properties, you may do it like this:
public class Person {
private String firstName = "";
private Integer age = 0;
public String firstName() { return firstName; } // getter
public void firstName(String val) { firstName = val; } // setter
public Integer age() { return age; } // getter
public void age(Integer val) { age = val; } //setter
public static void main(String[] args) {
Person p = new Person();
//set
p.firstName("Lemuel");
p.age(40);
//get
System.out.println(String.format("I'm %s, %d yearsold",
p.firstName(),
p.age());
}
}
Most IDEs for Java will automatically generate getter and setter code for you if you want them to. There are a number of different conventions, and an IDE like Eclipse will allow you to choose which one you want to use, and even let you define your own.
Eclipse even includes automated refactoring that will allow you to wrap a property up in a getter and setter and it will modify all the code that accesses the property directly, to make it use the getter and/or setter.
Of course, Eclipse can only modify code that it knows about - any external dependencies you have could be broken by such a refactoring.
My Java experience is not that high either, so anyone feel free to correct me. But AFAIK, the general convention is to write two methods like so:
public string getMyString() {
// return it here
}
public void setMyString(string myString) {
// set it here
}
From Jeffrey Richter's book CLR via C#: (I think these might be the reasons why properties are still not added in JAVA)
A property method may throw an exception; field access never throws an exception.
A property cannot be passed as an out or ref parameter to a method; a field can.
A property method can take a long time to execute; field access always completes
immediately. A common reason to use properties is to perform thread synchronization,
which can stop the thread forever, and therefore, a property should not be
used if thread synchronization is required. In that situation, a method is preferred.
Also, if your class can be accessed remotely (for example, your class is derived from
System.MarshalByRefObject), calling the property method will be very slow, and
therefore, a method is preferred to a property. In my opinion, classes derived from
MarshalByRefObject should never use properties.
If called multiple times in a row, a property method may return a different value each
time; a field returns the same value each time. The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that
they could fix the class by making Now a method instead of a property. Environment’s
TickCount property is another example of this mistake.
A property method may cause observable side effects; field access never does. In other
words, a user of a type should be able to set various properties defined by a type in
any order he or she chooses without noticing any different behavior in the type.
A property method may require additional memory or return a reference to something
that is not actually part of the object’s state, so modifying the returned object has no
effect on the original object; querying a field always returns a reference to an object
that is guaranteed to be part of the original object’s state. Working with a property
that returns a copy can be very confusing to developers, and this characteristic is frequently
not documented.
If you're using eclipse then it has the capabilities to auto generate the getter and setter method for the internal attributes, it can be a usefull and timesaving tool.
I'm just releasing Java 5/6 annotations and an annotation processor to help this.
Check out http://code.google.com/p/javadude/wiki/Annotations
The documentation is a bit light right now, but the quickref should get the idea across.
Basically it generates a superclass with the getters/setters (and many other code generation options).
A sample class might look like
#Bean(properties = {
#Property(name="name", bound=true),
#Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}
There are many more samples available, and there are no runtime dependencies in the generated code.
Send me an email if you try it out and find it useful!
-- Scott
There is no property keyword in java (like you could find it in C#) the nearest way to have 1 word getter/setter is to do like in C++:
public class MyClass
{
private int aMyAttribute;
public MyClass()
{
this.aMyAttribute = 0;
}
public void mMyAttribute(int pMyAttributeParameter)
{
this.aMyAttribute = pMyAttributeParameter;
}
public int mMyAttribute()
{
return this.aMyAttribute;
}
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
As previously mentioned for eclipse, integrated development environment (IDE) often can create accessor methods automatically.
You can also do it using NetBeans.
To create accessor methods for your class, open a class file, then Right-click anywhere in the source code editor and choose the menu command Refactor, Encapsulate Fields.
A dialog opens. Click Select All, then click Refactor.
Voilà,
Good luck,
For me the problem is two fold:
All these extra methods {get*/set*} cluttering up the class code.
NOT being able to treat them like properties:
public class Test {
private String _testField;
public String testProperty {
get {
return _testField;
}
set {
_testField = value;
}
}
}
public class TestUser {
private Test test;
public TestUser() {
test = new Test();
test.testProperty = "Just something to store";
System.out.printLn(test.testProperty);
}
}
This is the sort of easy assignment I would like to get back to using. NOT having to use 'method' calling syntax. Can anyone provide some answers as to what happened to Java?
I think that the issue is also about the unnecessary clutter in the code, and not the 'difficulty' of creating the setters/getters. I consider them as ugly-code. I like what C# has. I don't understand the resistance to adding that capability to Java.
My current solution is to use 'public' members when protection is not required:
public class IntReturn {
public int val;
}
public class StringReturn {
public String val;
}
These would be used to return value from say a Lambda:
StringReturn sRtn = new StringReturn()
if(add(2, 3, sRtn)){
System.out.println("Value greater than zero");
}
public boolean add(final int a, final int b, final StringReturn sRtn){
int rtn = a + b;
sRtn.val = "" + rtn;
return rtn > 0; // Just something to use the return for.
}
I also really don't like using a method call to set or get an internal value from a class.
If your information is being transferred as 'immutable', then the new Java record could be a solution. However, it still uses the setter/getter methodology, just without the set/get prefixes.
Related
I have two Classes like this:
#Data
#NoArgsConstructor
#AllArgsConstructor
public class FooCounts {
private Long countOfRows;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
public class DooCounts {
private Long countOfRows;
}
I created two Lists of the above types and did the following:
List<FooCounts> fooCounts = ...; //initialisation doesn't matter
List<DooCounts> dooCounts = ...;
Long countOfRows = 0L;
if(!fooCounts.isEmpty){
countOfRows = fooCounts.map(FooCounts::getCountOfRows).sum().longValue();
}
if(!dooCounts.isEmpty){
countOfRows = dooCounts.map(DooCounts::getCountOfRows).sum().longValue();
}
Is it possible to make these two 'if' blocks as one 'if' block by creating a method out of it? I mean something like this:
private Long fooDooCounts(List<T> fooDooCounts) {
if(!fooDooCounts.isEmpty){
countOfRows = fooDooCounts.map(fooDooCounts::getCountOfRows).sum().longValue();
}
Java is strictly namespaced. The name of a method/field are relevant only insofar as that they exist in the context of a type (hence, in java you can't define fields or methods outside of a type - because names do not mean anything outside of them), and the name of a type is only meaningful in light of the package it is in.
In other words, the actual name of string's toLowerCase method is java.lang.String::toLowerCase.
There is no way in java to say 'I want to call the toLowerCase method on this object, whatever the type of the object is, regardless of where the method comes from. Long as it is called toLowerCase, call it'. It just doesn't exist. You can see this in action in class files, where any invocation is necessarily always bound up with a fully qualified name (it would look like java/lang/String toLowerCase()Ljava/lang/String; in classfile-ese, but it's the same principle, just in classfile form).
There's a good reason for this.
Imagine these two types:
interface Gun {
void shoot(Person p);
}
interface Camera {
void shoot(Person p);
}
hopefully this illustrates the subtle but serious dangers of allowing you to write, in a programming language 'just call shoot(p) on this object, whatever it might be, if it has a shoot method, go for it'.
Hence, 'can you write code in java that fetches a field of a given name, regardless of what type the objects are, as long as it has a field of some name, just get the data out of it' - the answer is a very very simple: No, you can't, and you don't want to - that is not how java is designed to work, and going against the 'grain' of how a language wants to be used results in all sorts of maintenance headaches.
Fortunately, it also gives you the strategy to fix the problem: Ensure that the 'fetch operation' is the same fully qualified name. How do we do that? By introducing a type that unifies the definition of what countOfRows means, and then have your various classes implement it:
interface RowCounter {
long countRows();
}
Now we have a uniform definition. You can stick docs on this if you want. Then it is simply a matter of implementing it in your types:
class FooCount implements RowCounter {
#Override public long countRows() {
return countOfRows;
}
}
Because now the countRows method in your FooCount class is in fact just a more specific implementation of RowCounter::countRows, the fully qualified name of that method is com.pkg.RowCounter::countRows. Thus, you can now invoke it:
long sum(List<? extends RowCounter> rowCounters) {
long totalCount = 0;
for (var r : rowCounters) totalCount += rowCounters.countRows();
return totalCount;
}
and you can pass a list of FooCounter objects, or a list of BarCounter, or a list of RowCounter, etc.
This question already has answers here:
Set and Get Methods in java?
(16 answers)
Closed 8 years ago.
In my CS class I am just learning about classes and OOP.
So when you create a class you initialize a certain number of private variable.
I know you make them private because if they were public they would be easily changeable and could lead to a lot of bugs.
So we use get and set methods to change the variable. But that once again makes the variables very easy to change right? So whats the point of making them private in the first place?
Some benefits of using getters and setters (known as encapsulation or data-hiding):
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
As the above comment states, getters and setters encapsulate (i.e. hide) inner details of your class. Thus other classes that interact with yours, do not need to know about the implementation details.
For example, in the simple case you describe, instance variables are exposed via getters and setters. But what if you wanted to change your class so that you no longer used instance variables, but rather you persisted the values to disk. You could make this change to your class without affecting the users of your class.
Keep in mind also that getters and setters need not always be provided. If you do not want your class to provide a way to set or read these properties, then don't. Simply make them private.
get is used to obtain a value for an attribute and set is used to put a value to an attribute
ex:
private int variable;
public int getVariable(){
return variable;
}
public void setVariable(int aux){
variable=aux;
}
In general, is used to encapsulate an attribute.
reference:
Set and Get Methods in java?
Encapsulation or data hiding gives u more control on what values can be set to a field. Here is an example if you don't want a class attribute to have a negative value:
class WithoutGetterSetter {
public int age;
}
class WithGetterSetter {
private int age;
public setAge(int age) {
if(age < 0)
// don't set the value
else
this.age = age;
}
}
public class testEncapslation {
public static void main(String args[]) {
WithoutGetterSetter withoutGetterSetter = new WithoutGetterSetter();
withoutGetterSetter.age = -5;
WithGetterSetter withGetterSetter = new WithGetterSetter();
withGetterSetter.setAge(-5);
}
}
Get and Set methods are preferable to "public" variables because they insulate the users of a class from internal changes.
Supposing you have a variable "StockQty" and you made it public because that seemed like the easiest thing to do.
Later on you get a user requirement to track the history of stock over time. You now need to implement a SetStockQty() method so you can save the old quantity somewhere before setting the new quantity.
Now all the users of your class have to change there code, re-document and re-test.
If you had SetStockQty() method to begin with only you would need to change and test your code.
The second reason is you can have Getters without Setters effectivly making the variable "read only".
Traditionally, they are justified in terms of encapsulation. By providing moderated access to read and write the fields of a class, we supposedly reduce coupling.
In simpler language: by controlling the ways in which other classes can read and change our data, we reduce the ways in which our class's data can change. This means that the connections between classes are reduced, which reduces complexity.
However, the same logic says that getters and setters should generally be avoided unless there's an actual need for them, and there very seldom is such a need. For the most part, a class should "tend to its own knitting" - if there's a calculation to be done on this class's data, it should do it. If a value should be changed, it should do the changing.
For example, consider an object in space. It has a location specified as (x,y,z). We could possibly allow other classes to just set those arbitrarily - this would be horrible, obviously, but it's not obvious that a setter for these would be any better. What you really want is a constructor to set an initial position, and then methods to influence that position - for example, to register an impact or an acceleration. Then you're doing OO programming.
One word, Encapsulation.setters also allow you to control how values are entered into your program. Many new programmers like myself are often confused by this concept. I strongly advice you read this SO question
Being objective: it's all about best pratices!!!
1) IF necessary, expose your attributes with get methods.
2) IF necessary, allow attribute modification (state modification) using set methods;
Have both public get and set methods without treatment is the same as have the attributes public.
I'm currently working on a codebase where there are a few classes of variable, like database paths, which are simply represented as Strings. Most of the operations on these (non-)types are defined in a utility class.
I have created a new class to represent a database, with operations defined as instance methods, in traditional OOP style. However it is quite laborious to go through the large codebase and refactor it to use the new types. Does anyone have any advice as to how to do this quickly and effectively?
Migrate the utility class to use your new class. Then the utility class methods should only contain two statements. One for creating your class and the other is invoking your class. After that, you can inline the utility class methods thereby eliminating the need for it.
When you are finished with that, you need to look for a way to not instantiate your new class over and over again. This should be done by refactoring the local variable to an instance field which is initialized at construction time.
Database paths sound like they should be Strings to me. What else makes sense? And they should be externalized, either in configuration files or a database. That's the least of your problems.
Persistence has been so many times over (e.g. Hibernate, Spring JDBC, iBatis, etc.) that I'd wonder how you could possibly improve on them. If you have to go to the trouble of refactoring - and you must - I'd advise using anything other than what you've done.
If you must write something, Google for "generic DAO". You'll get stuff like this:
http://www.ibm.com/developerworks/java/library/j-genericdao/index.html
If your work isn't patterned after something like that, throw it away and re-think things.
A technique I've used in C# (and just ported to Java - apologies if I've made an error, I'm new to Java) is to create StringlyTyped classes, e.g. a base class
public abstract class StringlyTyped {
private String value;
public StringlyTyped (String value){
if (value == null){
throw new IllegalArgumentException("value must not be null");
}
this.value = value;
}
public String getValue() { return value; }
#Override
public boolean equals(Object other){
if (other == this) {
return true;
}
if (other == null || !this.getClass().equals(other.getClass())){
return false;
}
StringlyTyped o = (StringlyTyped)other;
return o.getValue().equals(this.getValue());
}
#Override
public int hashCode(){ return this.getValue().hashCode(); }
#Override
public String toString() { return this.getValue(); }
}
Then derived class
public class ProviderName extends StringlyTyped {
public ProviderName(String value) {
super(value);
}
}
And usage
public void Foo(ProviderName provider) {
}
It makes sense when you have methods with many String parametrers, e.g. you can avoid
public void Foo(String username, String password, String db, String table, String constraint)
and instead have code that is strongly typed like this:
public void Foo(UserName username, Password password, DatabasePath db, TableName table...)
etc...
I generally try to isolate the strings at the limit of the application/process boundary, such as when they are retrieved from a database or received via a web operation.
At that application/process boundary is often the ideal place to map/convert/deserialize the strings into a more proper object model, as supported by whatever language you are using.
Similarly, the object model can be mapped/converted/serialized back into string form as it exits your application/process boundary.
It is worth noting that this stringly typing can be somewhat subtle. I commonly see xml intruding into application and domain layers. A similar example from the .NET space would be failing to map ADO.NET DataTables (with their string column names and untyped field values) into classes/objects pretty much as soon as they are received. I have no doubt that there are many similar equivalents in the Java world. Stringly Typing is not just limited to date values, as the joke goes.
class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
void setYearOfBirth(Creature other) {
yearOfBirth = other.yearOfBirth; // is this correct it compiles fine
}
int getYearOfBirth() {
return yearOfBirth;
}
public static void main(String args[])
{
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d);
System.out.println(c.yearOfBirth);
}
}
Is there any mistake in this code?
Is "other.yearOfBirth" wrong? My faculty says it is wrong but it works fine for me.
As written, it will work, as you discovered. I suspect that there's a fundamental misunderstanding at play, though.
My psychic powers tell me that your instructor expected code more like the following:
class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
public void setYearOfBirth(Creature other) {
yearOfBirth = other.yearOfBirth;
}
public int getYearOfBirth() {
return yearOfBirth;
}
}
class Program {
public static void main(String args[]) {
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d);
System.out.println(c.yearOfBirth); // This will not compile
}
}
The misunderstanding is that you've only created one class-- your main application class. This effectively makes yearOfBirth a sort of hybrid global value that you can access from your main method. In more typical designs, Creature is a class that is completely independent of your main method. In that case, you must only access Creature through its public interface. You would not be able to access its private field directly.
(Note to any pedants out there: Yes, I know I'm simplifying.)
You have to ask your faculty to explain why they think it's wrong (its perhaps a question of style, or even a misunderstanding), so you can learn from it.
Ultimately this person is going to impact your grades. This is an excellent opportunity to have a positive interaction with them. The more involved your teachers are with teaching you personally, the better your opportunity for mastering your subject will be.
If on the other hand when you're told something is wrong you go away privately and ask the general internet community, there is a risk that you'll be told you're right and you'll end up a false sense of superiority over your teachers which will be very counterproductive.
i detect nothing wrong.
the code works, because an instance or class can access private members of other instances of the same class. this is by design.
No, there is no problem at all with it.
Look, it depends on the viewer opinion. But for a given context this code may be just perfect.
For some other context this may not be correct. So it depends of how is going to be used.
Accessing a private member directly from another instance, is correct ( not always desirable though, for instance when you're subclassing ) that's why it is private in first place. You are saying "Hey, this is mine and I know how to use it"
Using the default access modifier for the other two methods, says that your intention is they should not be used by other classes outside the package.
Probably the only thing I would add is to make the class final.
final class Creature
If you want to make it inheritable you probably have to review the get/set for the yearOfBirth attribute, but they way it is is perfect to me.
NOW The most important thing here, is that you understand what each part of your code does, and how it affects its behavior.
You should no code just by luck ( sorry I don't know what's the correct expression for this ) but you should know what you're doing each time you type something, and how do you intend to be used.
I see two "issues," though I hesitate to call them mistakes:
You're explicitly setting Creature c's age as 89, and then rewriting that age with the uninitialized default (!) of Creature d. If this is what you intend to do, then fine, but at the very least you're wasting a few cycles to set a value that you intend to throw out later.
You're possibly violating the JavaBeans naming conventions.
To explain the latter point: a lot of Java libraries and frameworks (notably JSP) rely on JavaBeans to treat the object as a component. I haven't dived deeply into the actual mechanisms used, but from what I've read it relies on Introspection of the JavaBeans class to infer properties and the types of those properties. By overloading your setter setYearOfBirth() to accept both an int and a Creature, you could throw off the Introspection. (See here for a decent introduction to JavaBeans.)
This is not a big deal -- its entirely possible that you won't use this class as a JavaBean, and if you do it's trivial to refactor it so it works. But your teachers would probably prefer something a little cleaner, like the following:
class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
int getYearOfBirth() {
return yearOfBirth;
}
public static void main(String args[])
{
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d.getYearOfBirth());
System.out.println(c.getYearOfBirth());
}
}
Now all of your access to yearOfBirth comes via the public getter methods, which helps encapsulation, and will prevent the code from breaking if your main method moves to another class. (As Greg D correctly pointed out.)
Also, this has the added benefit of making the intent of your code clear, which becomes more and more important when you start writing code for others to maintain and modify.
It's wrong because you're accessing a private member (you declared private int yearOfBirth) of another object although the class type is the same. You should use the public getter you defined instead: yearOfBirth = other.getYearOfBirth()
yearofBirth is a private int. Therefore the call to other.yearOfBirth would presumably fail...
Is it a good or bad idea to make setters in java return "this"?
public Employee setName(String name){
this.name = name;
return this;
}
This pattern can be useful because then you can chain setters like this:
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
instead of this:
Employee e = new Employee();
e.setName("Jack Sparrow");
...and so on...
list.add(e);
...but it sort of goes against standard convention. I suppose it might be worthwhile just because it can make that setter do something else useful. I've seen this pattern used some places (e.g. JMock, JPA), but it seems uncommon, and only generally used for very well defined APIs where this pattern is used everywhere.
Update:
What I've described is obviously valid, but what I am really looking for is some thoughts on whether this is generally acceptable, and if there are any pitfalls or related best practices. I know about the Builder pattern but it is a little more involved then what I am describing - as Josh Bloch describes it there is an associated static Builder class for object creation.
It's not bad practice. It's an increasingly common practice. Most languages don't require you to deal with the returned object if you don't want to so it doesn't change "normal" setter usage syntax but allows you to chain setters together.
This is commonly called a builder pattern or a fluent interface.
It's also common in the Java API:
String s = new StringBuilder().append("testing ").append(1)
.append(" 2 ").append(3).toString();
To summarize:
it's called a "fluent interface", or "method chaining".
this is not "standard" Java, although you do see it more an more these days (works great in jQuery)
it violates the JavaBean spec, so it will break with various tools and libraries, especially JSP builders and Spring.
it may prevent some optimizations that the JVM would normally do
some people think it cleans code up, others think it's "ghastly"
A couple other points not mentioned:
This violates the principal that each function should do one (and only one) thing. You may or may not believe in this, but in Java I believe it works well.
IDEs aren't going to generate these for you (by default).
I finally, here's a real-world data point. I have had problems using a library built like this. Hibernate's query builder is an example of this in an existing library. Since Query's set* methods are returning queries, it's impossible to tell just by looking at the signature how to use it. For example:
Query setWhatever(String what);
It introduces an ambiguity: does the method modify the current object (your pattern) or, perhaps Query is really immutable (a very popular and valuable pattern), and the method is returning a new one. It just makes the library harder to use, and many programmers don't exploit this feature. If setters were setters, it would be clearer how to use it.
I prefer using 'with' methods for this:
public String getFoo() { return foo; }
public void setFoo(String foo) { this.foo = foo; }
public Employee withFoo(String foo) {
setFoo(foo);
return this;
}
Thus:
list.add(new Employee().withName("Jack Sparrow")
.withId(1)
.withFoo("bacon!"));
Warning: this withX syntax is commonly used to provide "setters" for immutable objects, so callers of these methods might reasonably expect them to create new objects rather than to mutate the existing instance. Maybe a more reasonable wording would be something like:
list.add(new Employee().chainsetName("Jack Sparrow")
.chainsetId(1)
.chainsetFoo("bacon!"));
With the chainsetXyz() naming convention virtually everyone should be happy.
I don't think there's anything specifically wrong with it, it's just a matter of style. It's useful when:
You need to set many fields at once (including at construction)
you know which fields you need to set at the time you're writing the code, and
there are many different combinations for which fields you want to set.
Alternatives to this method might be:
One mega constructor (downside: you might pass lots of nulls or default values, and it gets hard to know which value corresponds to what)
Several overloaded constructors (downside: gets unwieldy once you have more than a few)
Factory/static methods (downside: same as overloaded constructors - gets unwieldy once there is more than a few)
If you're only going to set a few properties at a time I'd say it's not worth returning 'this'. It certainly falls down if you later decide to return something else, like a status/success indicator/message.
If you don't want to return 'this' from the setter but don't want to use the second option you can use the following syntax to set properties:
list.add(new Employee()
{{
setName("Jack Sparrow");
setId(1);
setFoo("bacon!");
}});
As an aside I think its slightly cleaner in C#:
list.Add(new Employee() {
Name = "Jack Sparrow",
Id = 1,
Foo = "bacon!"
});
It not only breaks the convention of getters/setters, it also breaks the Java 8 method reference framework. MyClass::setMyValue is a BiConsumer<MyClass,MyValue>, and myInstance::setMyValue is a Consumer<MyValue>. If you have your setter return this, then it's no longer a valid instance of Consumer<MyValue>, but rather a Function<MyValue,MyClass>, and will cause anything using method references to those setters (assuming they are void methods) to break.
I don't know Java but I've done this in C++.
Other people have said it makes the lines really long and really hard to read,
but I've done it like this lots of times:
list.add(new Employee()
.setName("Jack Sparrow")
.setId(1)
.setFoo("bacon!"));
This is even better:
list.add(
new Employee("Jack Sparrow")
.Id(1)
.foo("bacon!"));
at least, I think. But you're welcome to downvote me and call me an awful programmer if you wish. And I don't know if you're allowed to even do this in Java.
At least in theory, it can damage the optimization mechanisms of the JVM by setting false dependencies between calls.
It is supposed to be syntactic sugar, but in fact can create side effects in the super-intelligent Java 43's virtual machine.
That's why I vote no, don't use it.
It's not a bad practice at all. But it's not compatiable with JavaBeans Spec.
And there is a lot of specification depends on those standard accessors.
You can always make them co-exist to each other.
public class Some {
public String getValue() { // JavaBeans
return value;
}
public void setValue(final String value) { // JavaBeans
this.value = value;
}
public String value() { // simple
return getValue();
}
public Some value(final String value) { // fluent/chaining
setValue(value);
return this;
}
private String value;
}
Now we can use them together.
new Some().value("some").getValue();
Here comes another version for immutable object.
public class Some {
public static class Builder {
public Some build() { return new Some(value); }
public Builder value(final String value) {
this.value = value;
return this;
}
private String value;
}
private Some(final String value) {
super();
this.value = value;
}
public String getValue() { return value; }
public String value() { return getValue();}
private final String value;
}
Now we can do this.
new Some.Builder().value("value").build().getValue();
Because it doesn't return void, it's no longer a valid JavaBean property setter. That might matter if you're one of the seven people in the world using visual "Bean Builder" tools, or one of the 17 using JSP-bean-setProperty elements.
This scheme (pun intended), called a 'fluent interface', is becoming quite popular now. It's acceptable, but it's not really my cup of tea.
If you use the same convention in whole applicaiton it seems fine.
On the oher hand if existing part of your application uses standard convention I'd stick to it and add builders to more complicated classes
public class NutritionalFacts {
private final int sodium;
private final int fat;
private final int carbo;
public int getSodium(){
return sodium;
}
public int getfat(){
return fat;
}
public int getCarbo(){
return carbo;
}
public static class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder sodium(int s) {
this.sodium = s;
return this;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
Paulo Abrantes offers another way to make JavaBean setters fluent: define an inner builder class for each JavaBean. If you're using tools that get flummoxed by setters that return values, Paulo's pattern could help.
I'm in favor of setters having "this" returns. I don't care if it's not beans compliant. To me, if it's okay to have the "=" expression/statement, then setters that return values is fine.
I used to prefer this approach but I have decided against it.
Reasons:
Readability. It makes the code more readable to have each setFoo() on a separate line. You usually read the code many, many more times than the single time you write it.
Side effect: setFoo() should only set field foo, nothing else. Returning this is an extra "WHAT was that".
The Builder pattern I saw do not use the setFoo(foo).setBar(bar) convention but more foo(foo).bar(bar). Perhaps for exactly those reasons.
It is, as always a matter of taste. I just like the "least surprises" approach.
Yes, I think it's a good Idea.
If I could add something, what about this problem :
class People
{
private String name;
public People setName(String name)
{
this.name = name;
return this;
}
}
class Friend extends People
{
private String nickName;
public Friend setNickName(String nickName)
{
this.nickName = nickName;
return this;
}
}
This will work :
new Friend().setNickName("Bart").setName("Barthelemy");
This will not be accepted by Eclipse ! :
new Friend().setName("Barthelemy").setNickName("Bart");
This is because setName() returns a People and not a Friend, and there is no PeoplesetNickName.
How could we write setters to return SELF class instead of the name of the class ?
Something like this would be fine (if the SELF keyword would exist). Does this exist anyway ?
class People
{
private String name;
public SELF setName(String name)
{
this.name = name;
return this;
}
}
This particular pattern is called Method Chaining. Wikipedia link, this has more explanation and examples of how it's done in various programming languages.
P.S: Just thought of leaving it here, since I was looking for the specific name.
On first sight: "Ghastly!".
On further thought
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
is actually less error prone than
Employee anEmployee = new Employee();
anEmployee.setName("xxx");
...
list.add(anEmployee);
So quite interesting. Adding idea to toolbag ...
In general it’s a good practice, but you may need for set-type functions use Boolean type to determine if operation was completed successfully or not, that is one way too. In general, there is no dogma to say that this is good or bed, it comes from the situation, of course.
From the statement
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
i am seeing two things
1) Meaningless statement.
2) Lack of readability.
This may be less readable
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
or this
list.add(new Employee()
.setName("Jack Sparrow")
.setId(1)
.setFoo("bacon!"));
This is way more readable than:
Employee employee = new Employee();
employee.setName("Jack Sparrow")
employee.setId(1)
employee.setFoo("bacon!"));
list.add(employee);
I have been making my setters for quite a while and the only real issue is with libraries that stick with the strict getPropertyDescriptors to get the bean reader/writer bean accessors. In those cases, your java "bean" will not have the writters that you would expect.
For example, I have not tested it for sure, but I would not be surprised that Jackson won't recognizes those as setters when creating you java objects from json/maps. I hope I am wrong on this one (I will test it soon).
In fact, I am developing a lightweight SQL centric ORM and I have to add some code beyong getPropertyDescriptors to recognized setters that returns this.
Long ago answer, but my two cents ... Its fine. I wish this fluent interface were used more often.
Repeating the 'factory' variable does not add more info below:
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Foo.class);
factory.setFilter(new MethodFilter() { ...
This is cleaner, imho:
ProxyFactory factory = new ProxyFactory()
.setSuperclass(Properties.class);
.setFilter(new MethodFilter() { ...
Of course, as one of the answers already mentioned, the Java API would have to be tweaked to do this correctly for some situations, like inheritance and tools.
It is better to use other language constructs if available. For example, in Kotlin, you would use with, apply, or let. If using this approach, you won't really need to return an instance from your setter.
This approach allows your client code to be:
Indifferent to the return type
Easier to maintain
Avoid compiler side effects
Here are some examples.
val employee = Employee().apply {
name = "Jack Sparrow"
id = 1
foo = "bacon"
}
val employee = Employee()
with(employee) {
name = "Jack Sparrow"
id = 1
foo = "bacon"
}
val employee = Employee()
employee.let {
it.name = "Jack Sparrow"
it.id = 1
it.foo = "bacon"
}
If I'm writing an API, I use "return this" to set values that will only be set once. If I have any other values that the user should be able to change, I use a standard void setter instead.
However, it's really a matter of preference and chaining setters does look quite cool, in my opinion.
I agree with all posters claiming this breaks the JavaBeans spec. There are reasons to preserve that, but I also feel that the use of this Builder Pattern (that was alluded to) has its place; as long as it is not used everywhere, it should be acceptable. "It's Place", to me, is where the end point is a call to a "build()" method.
There are other ways of setting all these things of course, but the advantage here is that it avoids 1) many-parameter public constructors and 2) partially-specified objects. Here, you have the builder collect what's needed and then call its "build()" at the end, which can then ensure that a partially-specified object is not constructed, since that operation can be given less-than-public visibility. The alternative would be "parameter objects", but that IMHO just pushes the problem back one level.
I dislike many-parameter constructors because they make it more likely that a lot of same-type arguments are passed in, which can make it easier to pass the wrong arguments to parameters. I dislike using lots of setters because the object could be used before it is fully configured. Further, the notion of having default values based on previous choices is better served with a "build()" method.
In short, I think it is a good practice, if used properly.
Bad habit:
a setter set
a getter get
what about explicitly declaring a method, that does it for U
setPropertyFromParams(array $hashParamList) { ... }