0

I'm new to Java and I'd like to know what is the better and conventional programming.

When I want to change an existing object's attributes:

One way is to simply set the values by the set functions, seems more effective:

anExistVar.setX(newValue);
anExistVar.setY(2);
anExistVar.setSomething(null);

Another way is to create a new object (in overriding), seems more elegant and clear (Leaves some work to the garbage collector...):

anExistVar = new SomeClass(newValue, 2, null);

Maybe the answer depends on the number of the values that I need to change? Maybe in this case there is no significant efficiency differences?

(My question refers to JAVA or any language that the system manages the dynamic memory)

I read some discussions concerning the subject, but I did not get a definitive answer.

Thanks in advance!

ChiefTwoPencils
  • 13,548
  • 8
  • 49
  • 75
MeNa
  • 1,467
  • 9
  • 23
  • 1
    I think the answer may depend on the purpose of the process. I personally will not re-instantiate unless the context I'm within change. That's the purpose of the OOP: you're working with an object, and as long as you keep working with the same, you can deal with its properties via `getters` and `setters`, but when you change to work with a different object, then you can re-instantiate. Take as a example when you're interviewing an individual. You can talk and take notes about his age, hobbies, addresses, among others. You don't need to change page everytime you learn something new from him. – Noe Apr 06 '13 at 21:40
  • Long question and many answers but hardly understand what you are talking about here :) – Vitaly Apr 06 '13 at 21:44
  • @Noe, i dont need but i want, change them all in only one line, instead many lines. – MeNa Apr 06 '13 at 22:58
  • @Vitaly, as i said to WilQu, I just asking whether override and use in constructor when i want to set many of values together, is a good idea... – MeNa Apr 06 '13 at 22:58

5 Answers5

1

The second way allows you to use immutable objects, which have a some advantages. For example, since immutable objects can't be changed, you never have to copy them: this can be more efficient is some situations. This makes you create a new object every time you need to change a value, but objects with a short life cycle are collected efficiently by the gc.

Note that some languages, like Haskell, only have immutable ojbects.

WilQu
  • 7,131
  • 6
  • 30
  • 38
  • Thanks, but i just asking whether override and use in constructor when i want to set many values together is a good idea... – MeNa Apr 06 '13 at 22:48
1

In general, do the thing which will make the most sense six months from now. Java's optimized for garbage collecting newly created objects, so there's not much trouble efficiency-wise either.

rongenre
  • 1,334
  • 11
  • 21
0

Doesn't that depend on what you want? The first snippet modifies an existing object while the second creates a new one. References to the same object will see the new values in version 1 but not in version 2.

And when it's only one reference anyway: The first one is more verbose and thus possibly easier to comprehend. Moreover, the constructor should only take necessary stuff. (Without that, the object would be useless) Too many overloaded constructors also allow for easy confusion. I think it's better to have every assignment spelled out explicitly.

DasKrümelmonster
  • 5,816
  • 1
  • 24
  • 45
0

if you do not need the old oblect with old attribute values then change it. convention is to change it. else a reviewer would hunt to see why you did that. would wonder where the old object is being used now. to make clearer code is more important.

memory and garbage collector pauses would be an issue if thus in many places, many requests or in a loop. in short change orignal if functionality allows

tgkprog
  • 4,493
  • 4
  • 41
  • 70
0

I think the answer depends on what, exactly, you're actually trying to do here. Conceptually, the fundamental question is, do you the programmer think of the state of anExistVar after either updating its members or reassigning it entirely as a fundamentally new entity in your program? Or is it merely a modified version of the old thing?

If it's simply a modified version, why are you updating all of the member variables at once? The old object and the new one share the same name and memory location, but logically they don't seem to have any relationship between them. Note, however, that if you intend to update all member variables but fail to do so, you may think that there is no relationship between the old state and the new state and thus fail to realize that there is some holdover from the old state. In particular, there may be private member variables that have no corresponding public set methods, so you may not be able to entirely transform the object even if that's your intention. In short, this kind of radical transformation of an object is confusing because it's not immediately clear what you're doing or why, or whether you'll actually be successful. If, however, you think that the modified object is still essentially the same object (with, for instance, some of the original data), then it makes far more sense to modify the existing object than to make a partially-faithful copy.

If you're creating something fundamentally new, then it's probably best to declare it as a new object. If you want there to be some sort of relationship between the old object and the new object, there are a variety of techniques you could use, such as a static class member to keep track of the total number of instances of that class that have been instantiated. Or, if you want the construction of your new instance to be partially determined by public attributes of the old instance, then explicitly pass those attributes to the constructor.

As far as efficiency and the garbage collector go, there's probably no reason to be concerned either way. The point of the garbage collector is to relieve you the programmer of the burden of explicitly deleting things; you can't explicitly control its behavior, and it behaves efficiently enough that you really shouldn't have to worry about it. Running out of memory is more of a concern than overburdening the garbage collector. In the particular case you're describing, yes, the garbage collector will need to delete the old object, but that won't have a significant impact on the collector's efficiency. It would be problematic to maintain references to objects you no longer need, because the garbage collector wouldn't be able to collect those objects in case you reference them later; since that's not what you're doing here, it's probably best to just do whatever is clearest from a programming and logical standpoint.

Kyle Strand
  • 15,941
  • 8
  • 72
  • 167
  • You say at the end you can't explicitly control the garbage collector's behaviour, but you can invoke it with `System.gc()` and allow it to do its thing. – ChiefTwoPencils Apr 06 '13 at 21:51
  • Thank you for your detailed answer! 1) The old object and the new one **are not** share the same memory location on the heap. 2) i updating all of the member variables at once because i want change them all... – MeNa Apr 06 '13 at 22:54
  • @C.Lang, `System.gc()` doesn't actually force the garbage collector to do anything: http://stackoverflow.com/questions/1481178/forcing-garbage-collection-in-java – Kyle Strand Apr 07 '13 at 01:58
  • @MeNa, sounds like you should make a new object, then. As I said, when you update the entire thing, it doesn't seem like there should be any logical connection between the two objects, so they probably shouldn't *be* the same object. – Kyle Strand Apr 07 '13 at 02:00
  • I'm just getting started with Java, but the implementation neutral book "The Complete Reference(JDK7)" says "You can run the garbage collector on demand...`gc()`...". It provides proof, and works on my machine, by checking the memory before and aft. In earlier chapters it says what most quote about not having any guarantee when or if it will run. ? ? – ChiefTwoPencils Apr 07 '13 at 02:36
  • What do you mean by "it provides proof"? The fact that it works on your machine doesn't show that the garbage collector **must** run when `gc()` is called; it just shows that it ran when you tried it. Yes, it will *probably* run when called, but you are not *guaranteed* that behavior. In any case, the point is that you shouldn't *need* to explicitly control the gc, and in fact you *can't* completely control its behavior. – Kyle Strand Apr 07 '13 at 02:53