• Post Reply Bookmark Topic Watch Topic
  • New Topic

Factory methods?  RSS feed

 
Adam Chalkley
Ranch Hand
Posts: 518
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey guys I'm reading effective java and I came across one line that confuses me

A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.

I'm not sure what is meant by this,surely creating assigning a reference with a static factory method would result in a new object created especially if the factory method returns a new instance of that class which is why they are used?

thanks
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is what we used to have to write; if you look in the Java9 documentation you will find this constructor will be deprecated in Java9:-Now, Integers are immutable, so who needs two objects? Post‑Java5 version:-Who needs distinct objects? You will get true displayed from this code:-... whereas the old version would print false. All you achieve with the old version is slightly more memory consumption.
 
Adam Chalkley
Ranch Hand
Posts: 518
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Campbel thanks for the reply but isn't this



not creating two separate objects?
 
Paul Clapham
Sheriff
Posts: 22843
43
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:hi Campbel thanks for the reply but isn't this



not creating two separate objects?


It's possible that Integer.valueOf(x) returns a new, distinct object, every time it's called. On the other hand it's also possible that Integer.valueOf(x) returns the same object every time it's called for a given value of x. It might have a cache where it remembers what it last returned for, say, Integer.valueOf(123) and returns that same value every time that Integer.valueOf(123) is called in the future.

Now I said "possible" and "might" because I haven't looked at the official documentation for the Integer class. No doubt that documentation would have a better description of how it actually works. On the other hand there's no need for documentation to say whether a new object is returned every time or not, because it makes no difference. Objects of class Integer are immutable so two such objects based on the value 123 are indistinguishable.

However that's just an example of a factory method. Here's another:



So there's a factory method which always returns the same object. There's a lot of examples of that design in the standard API, such as the Locale.getLocale() method for one.
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:isn't this . . . not creating two separate objects?
If you approached the problem from first principles, then you wouldn't know. You could only say that the code might produce one object or it might produce two objects. But we aren't trying to work from first principles; there is much more information at our disposal:-
  • 1: Integer is an immutable type; it would be daft to try returning the same object repeatedly for a mutable type.
  • 2: The Java® Language Specification mandates that the same object be returned when boxing ints within a certain range, including 123.
  • 3: The documentation for Integer#valueOf() also says that the same object is returned for values within that range.
  • This discussion comes up regularly; a few years ago somebody showed how to alter the range for caching, but then the option only allowed an increase in the maximum value cached, not the minimum.
     
    Adam Chalkley
    Ranch Hand
    Posts: 518
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks guys,so what would be the purpose of creating a factory method that returned the same object?

    and how would this be done?
     
    Paul Clapham
    Sheriff
    Posts: 22843
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It seems you didn't really read my post a couple of posts back in which I explained that and gave an example.
     
    Adam Chalkley
    Ranch Hand
    Posts: 518
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Paul,

    I did I'll look it it a few more times,sorry,

    I'm starting to grasp the concept

    cheers =)
     
    Adam Chalkley
    Ranch Hand
    Posts: 518
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'm not too sure what you mean by


    Objects of class Integer are immutable so two such objects based on the value 123 are indistinguishable.


    cheers
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Not only are two Integers each representing 123 indistinguishable, but they also remain indistinguishable forever. If they weren't immutable, they could change their state and become different, but they don't. 123 is 123 and remains so forever. So, who needs two different Integers for 123?
     
    Adam Chalkley
    Ranch Hand
    Posts: 518
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    hey thanks for the reply Campbell much appreciated


    I understand what immutable means in terms of you can't extend that class and all of it's fields are marked final static,but why would it matter they were or were not immutable?

    thanks
     
    Ron McLeod
    Bartender
    Posts: 1603
    232
    Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    An immutable object cannot have its state changed after it has been constructed, so as in Campbell's example, once an Integer object has been created with a value of 123, it cannot be changed later.  Since it cannot be changed, there is no benefit in creating another object which represents the exact same thing.
     
    Paul Clapham
    Sheriff
    Posts: 22843
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:I understand what immutable means in terms of you can't extend that class and all of it's fields are marked final static...


    But you're understanding things backwards. Why that particular combination of requirements? Learning things that way means you don't really understand what's going on.

    An "immutable" object is one whose state can't be changed. ("Immutable" means "Can't be changed" in English.) But why do we care whether an object's state can be changed? It's because it's easier to look at some code involving immutable objects and understand what is happening with those objects. For example if you see



    and you know that the "person" object is immutable, then the debugging statement will tell you what was assigned to the "first" variable. If it's not immutable then it's possible that some other thread changed the "name" property of the object between those two statements and your debugging statement is lying to you. Okay, that's an artificial example because it's obvious how to deal with that particular problem but that's the point of immutable objects.

    So now you know what "immutable" means, you should go on and learn how to implement immutable objects in Java. And by the way your description of how to do that isn't correct... the rule you're missing is that there shouldn't be any methods which allow the object's state (its fields) to be changed. Static variables are irrelevant to this issue because they aren't part of the object's state. Only instance variables are.
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:. . . all of it's fields are marked final static . . .
    That is not actually correct. An immutable object does not have to have any static fields. If you are feeling pedantic, you would say that the static fields aren't part of the object at all because they belong to its creating class. It does not have to mark its fields final (but usually does). The defining part of an immutable object is that it has no mechanism whereby it can change its state. The class does not have to be marked final (but usually is); an alternative is to have only private constructors and make instances available only via factory methods. You are right however that you can't maintain immutability of classes which can be subclassed.


    thanks
    That's a pleasure.

    I seem to be repeating what Paul C has already said.
     
    Adam Chalkley
    Ranch Hand
    Posts: 518
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks guys,

    so correct me if I'm wrong so the Integer class checks (under the hood) to see if an Integer with the value of 123 was already created and if so returns the object that was already created with the value of 123?

    thanks
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
     
    Narendran Sridharan
    Ranch Hand
    Posts: 32
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The Main Idea behind factory method is to control the object creation behaviour. In case of the constructor, objects will be created all the time, we do not have any control. since we write the factory method, we can have any algorithm based on which objects can be created.

    Logger is also a good example, we never use the constructor for creating an object for LOGGER. we get the instance of LOGGER as below, in such cases, the LoggerFactory or manager creates only one instance of the object, the very first time it is called or loaded and reuses the same object for the further calls.

    private static final Logger LOGGER = LogManager.getLogger(AApgAssignmentBroker.class);
    or
    LOGGER.getInstance()
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!