5

I am having a doubt with method creations in a class for setting information.

  1. creating separate methods for setting each attribute

    class Address{
        private String name;
        private String city;
    
        public setName(String name) { ... }
        public setCity(String name) { ... }
    }
    
  2. creating single method for setting all attributes

    class Address{
        private String name;
        private String city;
    
        public setAddress(String name,String city) { ... }
    }
    

from above two ways which is preferable in memory point of view?

aioobe
  • 413,195
  • 112
  • 811
  • 826
satheesh
  • 1,443
  • 7
  • 28
  • 41
  • 2
    Show us what you mean with code samples for both approaches. – Jim Garrison Aug 30 '11 at 15:25
  • whats the purpose of this class? is it a value object? will you require to set each value independently? Do these values have to change after the creation of the object? What do you mean by "memory point of view"? Human memory or computer memory? – buritos Aug 30 '11 at 15:31
  • 1st example is fine, 2nd example is bad. Use a constructor. – BalusC Aug 30 '11 at 15:43
  • 1
    If you're really after mutable objects then getter/setter are ok. However immutable objects are getting more and more common: http://stackoverflow.com/questions/2848938 – SyntaxT3rr0r Aug 30 '11 at 15:46
  • +1 SyntaxT3rr0r. I could not agree with this sentiment more. – Mansoor Siddiqui Aug 30 '11 at 16:04

7 Answers7

4

Common practice is to use JavaBean style

class Address {
  private String name;
  private String city;

  public setName(String name){
    this.name = name;
  }

  public String getName() {
     return name;
  }

  public setCity(String city){
     this.city = city;
  }

  public getCity() {
    return city;
  }

}

Another common practise, which is quite similar to you second approach is to create immutable object. Parameters are passed to constructor instead of big setter method.

class Address {
  private final String name;
  private final String city;

  public Address(String name, String city) {
      this.name = name;
      this.city = city;
  }

  public String getName() {
     return name;
  }

  public getCity() {
    return city;
  }
}

From memory point of view, difference would be that second example is setting all attributes in constructor and all those attributes are immutable. In general, object constructed this way are safer when used by multiple threads.

In second example, there is no need for synchronization. You'd need to handle synchronization/memory issues when multiple threads using standard JavaBean object.

Arnost Valicek
  • 2,418
  • 1
  • 18
  • 14
3

Why not to use method #2

Your second example is not recommended because if you added a new field to the Address class, then do you add it into the existing setter method or do you create a new setter method? If you add it into the existing setter method, then any classes that called that method would be broken. And if you created a new setter method, then it is confusing for anyone who wants to use that class why certain fields are grouped together that way while others are not.

Using a separate setter method for each field that you wish to expose

The common practice is to have a single setter method for each field in your class that you wish to expose (i.e. your first example). Whether or not this is a good practice is debatable because it forces a class to be mutable. It is best to make an object immutable, if possible, for a number of reasons.

Initializing your fields using a constructor

One way to make a class immutable is by getting rid of the setter methods and instead making your fields settable via your class constructor, as below. The downside to implementing it this way is that if your class has a lot of fields, it may potentially lead to large, unreadable constructor calls.

public class Address {
    public String name;
    public String city;

    private Address(String name, String city) {
        this.name = name;
        this.city = city;
    }
}

Initializing your fields using the Builder pattern

Below is a completely alternative implementation (inspired by this article) that is a variation of the Builder pattern. It simulates object mutability without sacrificing readability.

public class Address {
    public String name;
    public String city;

    private Address() {}

    private void setName(String name) {
        this.name = name;
    }

    private void setCity(String city) {
        this.city = city;
    }

    static class Builder {
        private Address address = new Address();

        public Builder name(String name) {
            address.setName(name);
            return this;
        }

        public Builder city(String city) {
            address.setCity(city);
            return this;
        }

        public Address build() {
            return address;
        }
    }
}

With the above class, you could create an immutable instance of the Address class as follows:

Address address = new Address.Builder()
        .name("Mansoor's address")
        .city("Toronto")
        .build();

Which approach uses more memory?

From a memory point of view, there shouldn't be any difference since the size of a class in memory is dependent on the fields in the class. Since all three implementations have the same fields, they should take the same amount of space in memory, regardless of which approach you use.

Mansoor Siddiqui
  • 20,853
  • 10
  • 48
  • 67
  • it does mean only i am asking for setter methods ..tell me about any methods – satheesh Aug 30 '11 at 15:32
  • Commented on the "methods in general" aspect in my answer. – aioobe Aug 30 '11 at 15:35
  • I don't agree with you answer. Why is it common practice to have setters for each field? More than often one have internal fields in a class that one don't want to expose. The only place I know it to be common practice is in beans. –  Aug 30 '11 at 15:46
  • @Farmor It makes sense to be a common practice only for Java beans, but many non-bean classes use setters instead of constructor arguments. Just take a look at the Spring API (e.g. org.springframework.jdbc.core.JdbcTemplate) which is common use. Spring is heavily based around having setters on non-POJOs as well. – Mansoor Siddiqui Aug 30 '11 at 15:50
  • Of course you can be heavily dependent on setters on non-POJOs it's not what I objected but rather that it's common practice to declare a setter for each field in your class which isn't the case for normal classes. –  Aug 30 '11 at 15:58
  • See the JdbcTemplate class for a counter-example. – Mansoor Siddiqui Aug 30 '11 at 16:03
  • If I read the source code for that class even they declare classes in that class "file" which have fields set only in the constructor see private final RowCallbackHandler rch; line 1234 http://kickjava.com/src/org/springframework/jdbc/core/JdbcTemplate.java.htm –  Aug 30 '11 at 16:11
  • One other comment which more correspond to what I objected and not the semantics for initializing the fields. Lets say I have a field in my class describing the objects state. The state would neither be set in the constructor arguments or in a setter. It would be initiated by the constructor and updated bu regular methods. But it would be class internal and not exposed in any way, not as a constructor argument and not by a setter nor a getter. –  Aug 30 '11 at 16:15
  • It's true, it's not 100% dependent on setters, but just go to http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html and take a look at how many setters the class has for fields that can't be initialized through the constructor. And the class isn't a java bean. Hence, that's why I didn't specifically refer to Java beans in my answer. That's all I'm saying. :P – Mansoor Siddiqui Aug 30 '11 at 16:15
  • @Farmor let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3007/discussion-between-mansoor-siddiqui-and-farmor) – Mansoor Siddiqui Aug 30 '11 at 16:19
2

I can't see how the two approaches would be any different memory-wise.

Choose the approach that makes most sense to have in the interface of the class.

I would recommend to go with approach 2 only if both properties are logically strongly related, or if there is some class invariant that you don't want to temporarily break (even temporarily).

In your Address example, I would definitely go with two setter methods, since when talking about addresses, the name and city are quite unrelated.


For methods in general I'd say that whether or not you split a method up in two has little effect on memory consumption. Each object doesn't get its own set of methods allocated. The memory containing the methods is shared between all instances of a class.


Rule of thumb: Strive to make the interface of your class clean and logical.

aioobe
  • 413,195
  • 112
  • 811
  • 826
1

This is not a clear question. Do you mean, would you rather have two methods like setFoo(String) and setBar(int), or one method like setFooBar(String, int)? It really depends on whether these are logically different properties, in which case you want individual methods, or whether it often (or only) makes sense to set them together. You could provide both.

Neither has any impact on memory, no.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
1

The JavaBean standard is to have getters and setters for each property: http://en.wikibooks.org/wiki/Java_Programming/Java_Beans. If you don't want to follow that standard convention, its what makes the most sense for your shop. As per other answers on this thread, there probably is a minimal memory delta, if any.

atrain
  • 9,139
  • 1
  • 36
  • 40
1

Nb.1 without a doubt.

And you don't write that code by hand, only declare your fields.

Then you let Eclipse do the rest for you.

In Eclipse use Source --> generate getters and setters.

A very similar construct as #2 is done in the objects constructor.

The updated question with regards to memory. Don't worry one second in production code for the memory difference between those two ways.

0

You generally write a setter and a getter method for each attribute.

I don't really see the case when one method is enough for setting all the attributes. In this case, all attributes should have the same value? Or you always would have to pass parameters for all attributes. Both cases are not really what you want. So you should clearly prefer your first approach.