What do you call this? - java

Is there a name for this techinique (method calls returning objects upon which another method call is made on the same line)?
String pAID = commonAssets.getApplicationServerSettings().getSetting("plivoAuthID");
instead of
ApplicationServerSettings applicationServerSettings = commonAssets.getApplicationServerSettings();
String pAID = applicationServerSettings.getSetting("plivoAuthID");
Also, when I do the first, Eclipse doesn't prompt me to import the class ApplicationServerSettings, but it does if I use the second code style.
Also, are these two styles merely preferences?

The technique is called method chaining.
String pAID = commonAssets.getApplicationServerSettings().getSetting("plivoAuthID");
Definition from the wiki:
Method chaining, also known as named parameter idiom, is a common
syntax for invoking multiple method calls in object-oriented
programming languages. Each method returns an object, allowing the
calls to be chained together in a single statement without requiring
variables to store the intermediate results.[1] Local variable
declarations are syntactic sugar because of the difficulty humans have
with deeply nested method calls.[2][3] A method chain is also known as
a train wreck due to the increase in the number of methods that come
one after another in the same line that occurs as more methods are
chained together[4] even though line breaks are often added between
methods.
Your second question:
Also, when I do the first, Eclipse doesn't prompt me to import the class ApplicationServerSettings, but it does if I use the second code style.
From the definition again "Each method returns an object, allowing the calls to be chained together in a single statement without requiring variables to store the intermediate results." That is why it does not prompt you to import the class ApplicationServerSettings.
Another example (besides the want you introduce) that looks simpler:
Take a look at the wiki example:
class Person {
private String name;
private int age;
// In addition to having the side-effect of setting the attributes in question,
// the setters return "this" (the current Person object) to allow for further chained method calls.
public Person setName(String name) {
this.name = name;
return this;
}
public Person setAge(int age) {
this.age = age;
return this;
}
public void introduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
// Usage:
public static void main(String[] args) {
Person person = new Person();
// Output: Hello, my name is Peter and I am 21 years old.
person.setName("Peter").setAge(21).introduce();
}
}

It's often called fluent syntax.
IMHO it's a matter of style, there's no right or wrong.
Fluent syntax is more concise, which is sometimes a good thing.
The other variant is more handy for source-level debugging. You can step through the statements and inspect the intermediate results.

Related

why we can't use multiple this() in Constructor Overloading?

i'm newbie in this world currently i'm learning java and i wanna to know why i can't use multiple this() in a constructor someone can tell me why please?
public class Student {
private String name;
private int age;
public Student(String name) {
System.out.println("Name of Student : " + name);
}
public Student(int age)
{
System.out.println("Age of student = " + age);
}
public Student()
{
this("Alex");
this(22); //Error in this line:Call to 'this()' must be first statement in constructor body
}
public static void main(String[] args){
Student student=new Student();
}
}
Analogy from one newbie java coder to another:
You log into your Starbucks app, looking to place a new order of drinks. (1) If you tap “Buy with one click!” on the frappuccino image, it will create a new order that has a frappuccino in it, finalize the order, and place it all in one go. This is what your first two Student constructors do. (2) Or, you could just click the button, “Start a new order”, and you won’t have anything in your cart yet. The second option is what you have chosen to do in your code. Remember: “new Student();” is ONE new order because there is only ONE new keyword.
If you have ever tried to place an order, you know that you cannot place an order if the order contains nothing. So instead of immediately sending it to your Starbucks location, it gives you a chance to add items to your order. Everything that you want in your order goes in between the parentheses ().When you called “this(“Alex”);”, you were really filling your order with ONE “Alex” drink and then placing it because you closed the parentheses (told the app, “this is what is in my cart for my order”).
When you then called “this(22)”, your code got confused because you were trying to add a 22 drink to an order you already placed. You cannot order a drink and then, 5 minutes later, add another drink to the SAME order.
Suggestion: make a constructor Student(name, age) and call this("Alex", 22) instead.
Alternatively: call this(22) inside Student(String) instead!
The main purpose of using this keyword to call the current class constructor inside other constructor.
you can call the current class constructor in first line of the constructor otherwise you get compile time error.
The reason if you create the object to call the constructor first check they any current class constructor is present or not if it present execute the constructor first and after that, this constructor is executed.
why we cannot use multiple this() in one constructor?. Because inside the constructor you can call one constructor at a time.

What does "void" mean as the return type of a method? [duplicate]

This question already has answers here:
Can someone explain a void return type in Java?
(5 answers)
Closed 6 years ago.
I'm confused about "void",
as it pertains to methods.
I don't know what the distinction between two methods is when one has "void" and another doesn't.
For example, if I do:
Public meth (int amount)
{
amount = initial * interest;
return amount;
}
( not sure if it was right, or even valid, to take the name "amount" and name it the same thing as my formal parameter, but what makes sense here is that you're performing a calculation and returning the result)
Then, if I did something like:
Public void Testing (int array[])
{
//code that would modify the internals of an array
}
Would the second one have no "return" because it's more of a general method, that can be applied to any integer array, while the first one is about doing work on specific variables?
Would also appreciate one or two more examples of when I would or wouldn't be using "void" and "return".
One other thing that seems to confuse me is calling methods.
I know sometimes I'll do something like, for example, using the Testing method above,
Testing(ArrayName);
Other times, it will be like:
NameOfWhateverImApplyingMethodTo.MethodName();
And then there are times when things will be done properly by:
Thing1.MethodName(Thing2);
Which circumstances would I switch the syntax for method calls like this?
Java is case sensitive, so the modifier Public is invalid, use public
You can't define a method as public methodName(int a), only a constructor has this signature, a method must be public void methodName(<signature>) for methods that don't return anything or public <return type> methodName(<signature>) for methods that do.
Void basically means that the method will not return anything.
If you did
String name= "tim";
public void getName(){
return name;
}
This would result in an error, because the getName method is returning a string object called name, but the method declaration is saying I am returning nothing - because it is void.
Instead the method should be :
String name = "tim";
public String getName(){
return name;
}
Now when the method getName() is called it will return a string object "name" with "tim" inside of it :)
You might have void for a set method. So for example
String name = "tim";
public void setName(String newName){
this.name = newName;
}
When this method is called you would use setName("Andy"); and it would set the value of the name variable to be "Andy". Nothing is returned in this method, because it is setting something, but there is no need to send anything back, so we use void on the method declaration.
Hope this helps.
The method that has void as return type does not return anything. For example you want to set a field firstName in your class. You will write a setting method like
public void setFirstName(String n) {
this.firstName = n;
}
As you can see you are just setting a class variable and does not require to return anything.
If you dont use void then you have to provide a return type for method. Like if you wish to write a getter for above variable as:
public String getFirstName() {
return this.firstName;
}
Once you provide a return type, you will have to return a value of that type otherwise your code will not compile.
Calling a method can be done based on where you are calling it from and what modifier is used:
If you are calling the method from the same class then you can simply write firstName = getFirstName()
If you are calling the method from another class then you require object of method's class as qualifier like personObject.getFirstName()
If you are calling a static method then you require class name as qualifier like Person.getFirstName();
Return type is what you get out of it. When you call it, what are you hoping to get back? For instance, if the method gets the average of two numbers, then you're expecting a number back, so the return type will be a number type, like "int" (integer).
You can see what it should be using that logic or by looking in the method for the word return - what comes after return is what is returned, and its type should be declared in the method (e.g. if it says "return 4;" it's returning an int, and should be e.g. public int getFour()
You also asked about e.g. testing() vs testing(word)
I remember having the same difficulty. The distinction between the two also relates to the method declaration line. I'll illustrate.
public String testing(){
return "a word";
}
Calling this method by doing "System.out.println(testing());" should print "a word". Calling this method by doing "System.out.println(testing("a word"));" will give you an issue - this is because when you call testing, it looks at the appropriate method: one in the right class, with the right return type and with the right arguments/parameters. If you're calling testing("a word"), that means you're using a String as an argument (because "a word" is a string), and so it tries to use the testing(String aString) method - which doesn't exist.
So you use empty brackets when the method takes no input, and you put stuff in brackets when the method expects stuff. This should be less confusing than it sounds, because it's usually logical - if you want to call a method that returns an average, you need to ask yourself "Average of what?" You'd probably need to supply it with the values you want the average of.
Moving on: (a) testing() versus(b) AClass.testing() versus(c) aclass.testing() -
In (a), there's no class specified. Therefore, if you call it from that class, Java can guess which class: this one, and it'll work. From any other class, it won't know what you're talking about, and might even insult you.
In (b), you're specifying a class in general - therefore it'll know what class to find it in - and it'll work if it's a "static method". *[see bottom]
In (c), you're specifying an instance of AClass you want to run "testing()" on*.
For instance, imagine you've created a class called Business. You make a hundred Business objects by specifying for each a name, number, address.
e.g.
Business b = new Business(name, number, address);
Then in the Business class you have a method "getName()". This method takes no argument - you could see that the brackets are empty - so if, from another class, you call "Business.getName()", how could it know which name you want? You've just made a hundred businesses!
It simply can't. Therefore, for such a method, you'd call "b.getName()" (b being the Business we created above) and it would get the name for this instance of a Business - namely, b.
I'm happy to help, so if you're confused about any particular parts of what I just wrote please let me know and I'll try to elaborate!
edit: A bit on static methods:
Static methods don't belong to an instance of the class. getName(), for example, would get the name of this Business - ie, this instance of the Business class. But let's say that in the Business class you made a method that took the first letter of each word in a String and transformed it to uppercase - like if you wanted to make the business names look more professional when you printed them out.
public static String stringToUpperCase(String aString){
aString = aString.substring(0, 1).toUpperCase() + aString.substring(1);
return aString;
}
And to use that, you change the getName() method from:
public String getName(){
return name;
}
to
public String getName(){
return stringToUpperCase(name);
}
The new method is used here to make the name have an uppercase first letter - but that is the extent of its involvement with the Business class. You notice it doesn't ask for information about the name, address, or number for a particular business. It just takes a string you give it, does something to it, and gives it back. It doesn't matter whether you have no Businesses or a hundred.
To call this method, you'd use:
System.out.println(Business.stringToUpperCase("hello"));
This would print Hello.
If it were not a static method, you'd have to make a new Business first:
Business b = new Business("aName", "aNumber", "anAddress");
System.out.println(b.stringToUpperCase("hello"));
And if the method did need access to more Business-instance information (like a business's name number or address) it wouldn't be able to be an instance variable.
The first example, a method without a return type at all, is a constructor; used when an instance is created with new. However, you can't return a value from a constructor. Something like,
this.amount = initial * interest; // return amount;
Sets the field amount to initial * interest.

Java Constructor Chaining [duplicate]

This question already has answers here:
How to avoid constructor code redundancy in Java?
(4 answers)
Closed 9 years ago.
Hi I am just learning about constructor chaining in Java and had some questions...
First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.
In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?
import java.util.*;
class Employee
{
private String name;
private double salary;
public Employee()
{
this("James Bond", 34000);
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public static void main(String[] args)
{
Employee a = new Employee();
}
}
Actually I believe the most common use of chained Constructors is when the Constructor does more than just setting the member variables.
static int numOfExamples = 0;
public Example(String name, int num)
{
this.name = name;
this.num = num;
numOfExamples++;
System.out.println("Constructor called.");
Log.info("Constructor called");
}
public Example()
{
this("James Bond",3);
}
That way we don't have to write the code for logging and incrementing the static variable twice, instead just chaining the constructors.
Chaining constructors like this is useful to avoid repeating code, and helps with maintainability:
public MyClass(int x, double y, String z) {
// set fields
}
public MyClass() { // i.e. a constructor that uses default values
this(42, 4.2, "hello world"); // x is 42, y is 4.2, and z is "hello world"
}
If we didn't use the chain, and wanted to change how the x argument (for example) is processed when constructing an instance of MyClass, we would have to change code in both constructors. With the chain, we only need to change one of them.
1) As others have said, it's for code maintenance, basically the idea is that you only write one piece of code once, which means you only need to edit it once, there is no risk of overlooking something when editing your methods and the two accidentally becoming different.
Personally I tend to use this differently than in your example. Like so:
Employee() {
setupStuff();
}
Employee(String name) {
this();
this.setName(name);
}
This is a nice way of doing things, because potentially your setter can be way more complicated than just setting a member in the class. So basically what this does is puts calling the empty constructor and then a setter into a single method, making it much easier for anyone using the class.
2) The constructor being called doesnt't create a different object at all, it creates this object. Note that there is no new keyword used. Basically you're just calling a different method inside your constructor, except that method happens to also be a constructor.
Every time you want to allow constructing an object wit default values, and also want to allow creating the same object with non-default values. Let's imagine a DateTime class. You could want to initialize it with the current time by default, or with a specific time. Imagine a Car class. You could imagine constructing it with Black as the default color, or with a specific color. This kind of situation is very common. See java.util.ArrayList or java.util.Locale, for concrete examples.
It's stored in the name field. So you access it, from the object itself, with this.name (this being optional, just as in the getName() method).
How do I access this new "James Bond" object for future use?
Because you saved the values of name and salary as fields of your employee class, then inside the employee class you can use those fields, and outside your employee class you can use the getter/setter methos of your employee class

ArrayList references behavior

I am totally confused with ArrayList behavior. Wrote really long post, then realized no one is going to analyse huge code, so just core of the problem. Numbers are for convenience, but in my app these 0 and 24 are dynamic values.
ArrayList<VoipBlock> sortedBlocks = new ArrayList<VoipBlock>();
VoipBlock vb3 =new VoipBlock();
vb3=sortedBlocks.get(0);
vb3.setPacketNumber(24);
Essentially my final aim is to: modify and add back to arrayList as new value. However when I do that the guy at position 0 in ArrayList -> unsortedBlocks.get(0); replicates all the changes done to vb3 which of course is not what I want. I want vb3 acquire same values as VoipBlock inside of ArrayList, but I want it to be detached.
This is yet another case of passing by reference. I hate technical explanations - Java passes everything by value, BUT in some cases it passes references by values - this is same as saying not-oily oil. Please help.
It reminds me my start of learning JavaScript - I hated the language - until I watched proper materials at lynda.com - JavaScript Good Practices? - Diagrams killed me. It is the lazy description that turns us-youth away from brilliant technology, not the technology itself.
Please don't let it bother my stress and don't be in any way offended by me, it is just general complaining, maybe someone will look at it and make life better :-)
Thanks for Your time,
Desperately awaiting for help :-)
To achieve your objective you can use clone method. you have to override this method in VoipBlock class
Lets say VoipBlock is as follows
public class VoipBlock {
private int packetNumber;
private String type;
public int getPacketNumber() {
return packetNumber;
}
public String getType() {
return type;
}
public void setPacketNumber(int value) {
packetNumber = value;
}
public void setType(String value) {
type = value
}
public VoipBlock clone() {
VoipBlock clone = VoipBlock();
clone.setType(this.getType());
clone.setPacketNumber(this.getPacketNumber());
return clone;
}
}
So, using the same code you can do like as follows
ArrayList<VoipBlock> sortedBlocks = new ArrayList<VoipBlock>();
VoipBlock vb3 =new VoipBlock();
sortedBlocks.add(vb3);
vb3=sortedBlocks.get(0).clone();
vb3.setPacketNumber(24);
Note that upon calling clone method in above code segment, vb3 get assigned with a new VoipBlock instance. And already inserted VoipBlock to the array remains unchanged.
if you are looking to have kind of sample instances of VoipBlock instances which you later wanted to use in creating similar instances like them. check on immutability/mutability aspect of the code. check "Effective Java" by Joshua Blouch
The following will always copy the reference of b to a:
AnyClass a = ...;
AnyClass b = ...;
a = b;
What you want is probably to clone the object:
a = b.clone();
If I understand correctly, you're a bit unsure about how references and values work. I think the rule of thumb is that primitive types like int, char, boolean and maybe String are copied but Objects just have their reference passed.
The line vb3=sortedBlocks.get(0); completely replaces whatever vb3 used to be with the first thing in the ArrayList. And yes, it won't be a copy, it will be a reference to the same object in memory. So whatever you do will affect both of them. You need to either manually copy over all the information you need or to use a clone() or copy() function.
So for example, in your code, the line VoipBlock vb3 =new VoipBlock(); is a bit redundant because you're overwriting the new instance straight away.
What you really need here is to either use a copy constructor or declare VoipBlock to be Clonable so you can use the clone() method.
What you are interpreting as passing by reference is not actually passing by reference. Java objects are really pointers. Because of this you are passing the value of the pointer. So when you do:
vb3=sortedBlocks.get(0);
you are really assigning vb3 to point to the same locations in memory as sortedBlocks.get(0). Therefore when you manipulate vb3 properties through their setters, the result is seen in both.
If you want two separate pointers you need to use the new keyword or use the clone() method which does this under the hood.
An example to prove this is:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class Main {
public void doSomething(Person p) {
p = new Person("Bob");
System.out.println(p.getName());
}
public static void main(String[] args) {
Person p = new Person("Billy");
System.out.println(p.getName());
doSomething(p);
System.out.println(p.getName());
}
}
Since Java is pass by value the output will be: Billy, Bob, Billy. If Java were pass by reference it would be Billy, Bob, Bob. If I did not do the new Person in the doSomething() method and instead used the setName() method I would end up with Billy, Bob, Bob also but this is due to the fact I'm now modifying off the same pointer not that I passed by reference as the example above proves that's not the case.

Is it bad practice to make a setter return "this"?

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) { ... }

Categories