Under what circumstance would you use field variable instead of local variable? I found it a bit hard to decide when a variable is used in 2 or more methods in a class. I tend to use local variables and pass them to another method.
Thanks,
Sarah
In object-oriented terms, does the variable make sense as an attribute of the object? If so, you should make it a field variable. If not, it can go either way.
Remember the Single Responsibility Principle -- well-designed classes should have only 1 responsibility, and thus only 1 reason to change.
A field denotes some kind of state related to an instance of your class. For instance, a BankAccount could have a balance field.
You should never use a field to simplify passing data from one method to another method. That's simply not its purpose. Doing so also makes your methods intrinsically thread unsafe or require synchronization.
A local variable is just a temporary store of data used to support an operation being done by a method. For example,
public void addInterest(double rate) {
double toAdd = rate * balance;
logTransaction("Interest", toAdd);
balance += toAdd;
}
toAdd here makes no sense as a field since it is temporary to the operation, not a part of the account's state.
I would definitely not pass variables around to other methods unless there's a very specific reason. If the variable is used multiple times in the class, make it a field variable. This almost always makes your code much more flexible too.
In general, you can also think if the variable makes sense as a part of the class. That is, it makes sense to have a Car class have the variable numOfMiles, even if it's only used a few times. However, if one method is int GetAmountOfGasUsed(int milesThisTrip) it makes sense to pass in the miles variable as a local variable because the distance you travel is probably not specific to the car.
If the methods that use the variable need to modify the value as well, then by all means make it a field variable. But, if they only read the value, you can safely pass it around.
Related
I have a class.
public CarSold{
static int count;
CarSold(){count++;}
// Other code
}
Now this is running in multithreading enviroment. And I read here that constructors are not implicitly syncronized.
In that case, there is a chance that I don't have the correct count of cars sold in the count variable.
What is the way to make sure that it has a correct count?
I can think of 2 ways.
Class level locking inside the constructor using synchronized(CarSold.class)
I can use AtomicInteger.
Can this 2 approach solves the problem ?
And is there is any other way?
Thanks.
You don't synchronize a constructor, that doesn't make any sense semantically, you synchronize the access to the variable. Which can happen from anywhere that has access to it.
What you are looking for in this case is AtomicInteger.
"Now this is running in multithreading enviroment. And I read here that constructors are not implicitly syncronized."
You might have already got the logic but just wanted to mention it again. When you synchronize a method, may it be constructor, it creates lock on 'this' object which is still not initialized and null in case if you are trying to synchronize the constructor. But You can create a separate instance object and use a lock on that object. Chances are the instance variable you are trying to use as lock is also not yet initialized. In that case you will get NP exception.
Now, important thing is from Java 6 final instance variables are thread safe so use can use a final object for locking in constructor.
If you are locking on XYD.class it will be application wise lock which might be valid in your case but sometimes you need instance level lock and in that case you can use above approach.
Can this 2 approach solves the problem ?
Yes.
I tend to think that most of the time that variable returning methods are invoked to assign the return value to a variable, e.g.:
return1 = object.DoSomething();
Nevertheless, Apart from executing the method: What happens when a returning method is invoked and the return value is not assigned to a variable? e.g:
object.DoSomething();
Is this a good practice? Where does the return goes?
JB Nizet made a remarkable comment stating that methods are implemented for most cases. Kind of explains why this situation occurs often.
People do it all the time. If you don't need the variable that the method returns, than you don't have to assign it to anything.
Bear in mind, that sometimes the return variable has some meaning, like whether or not the operation was successful, and you might want to do something with that information
I think this is valid. Unless you have a need to use the return value further down, it is better to ignore (You can save from code review tools flag as un-used variables).
Method execution and flow stays same, only thing is you are ignoring return value.
It is good practice or not depends on situation, for example if you have requirement like how many rows update on executing query, you need to capture return value, but most of the times developers ignore this because they don't need to track how many records were updated.
The method is invoked in the same fashion as it would when the return value is assigned to a variable.
This is a perfectly acceptable practice, and is a necessity when invoking void methods, which do not return values (and therefore cannot be assigned to objects).
- Its always better to use void as a return type where you don't want to assign or use the returned value.
- It won't cause any problem in its efficiency but will be considered as loose programming.
That code will compile and run perfectly normal.
Suppose I am writing a method foo(int i) in Java.
Since i is passed by value it is safe to change it in foo. For example
void foo(int i) {
i = i + 1; // change i
...
}
Is it considered good or bad practice to change arguments of methods in Java?
It's considered bad practice in general, though some people overlook it as you can see in the other answers.
For parameters like primitives that are directly passed in by value, there is no advantage in overriding the original variable. In this case you should make a copy as suggested by #João.
For parameters whose reference is passed in by value (objects), if you modify the handle to point to a different object, that is downright confusing. It's all the more important because modifying the contents of an object passed as a parameter will modify the original object too.
If you replace the object referred to by the handle, and then modify its contents, the object referred to by the original reference in the caller will not be replaced, but someone reading the code might expect it to be.
Whereas if you don't replace the object, and modify the contents, the method calling your method might not expect this change. This category generally comes under security-related bad practices.
It's merely a personal opinion, but I think it can be confusing for other people that may want to use the original parameter value later in that code, and may not notice that it has already been changed.
Plus, it's cheap to simply create another variable and assign it the modified value (i.e., int j = i + 1).
Since i is passed by value it is safe to change it foo()
It is absolutely safe even when you pass an object reference because they are local: i.e., assigning a new reference to the local reference will not have any impact on the original reference in the calling code
It's your personal choice. However i would not change the argument values as one might loose the track of the actual value passed in to this method.
What is important to note is that i = i + 1; does not really change i. It only changes your local copy of i (in other words, the i in the calling code won't change).
Based on that, it is a matter of readability and avoiding unexpected behaviour in your code by complying with the POLS (Principle Of Least Surprise).
Neutral. But it would be considered a better practice by many people to change the method to:
void foo(final int i) {
int j = i + 1; // not change i
...
}
Feel free to work either way.
Depends on context. I lean towards "bad practice", for two reasons:
Some people may think the original value is being changed.
It may make the code harder to reason about (mitigated with appropriately-short methods).
A third issue pops up when it's a reference value. If you modify the parameter reference to point at something else and change its state, the original won't be modified–this may or may not be what's intended. If you create another reference to the parameter and change the new reference's state, the parameter's reference will be changed–which also may or may not be what's intended.
A very unimportant question about Java performance, but it made me wondering today.
Say I have simple getter:
public Object getSomething() {
return this.member;
}
Now, say I need the result of getSomething() twice (or more) in some function/algorithm. My question: is there any difference in either calling getSomething() twice (or more) or in declaring a temporary, local variable and use this variable from then on?
That is, either
public void algo() {
Object o = getSomething();
... use o ...
}
or
public void algo() {
... call getSomething() multiple times ...
}
I tend to mix both options, for no specific reason. I know it doesn't matter, but I am just wondering.
Thanks!
Technically, it's faster to not call the method multiple times, however this might not always be the case. The JVM might optimize the method calls to be inline and you won't see the difference at all. In any case, the difference is negligible.
However, it's probably safer to always use a getter. What if the value of the state changes between your calls? If you want to use a consistent version, then you can save the value from the first call. Otherwise, you probably want to always use the getter.
In any case, you shouldn't base this decision on performance because it's so negligible. I would pick one and stick with it consistently. I would recommend always going through your getters/setters.
Getters and setters are about encapsulation and abstraction. When you decide to invoke the getter multiple times, you are making assumptions about the inner workings of that class. For example that it does no expensive calculations, or that the value is not changed by other threads.
I'd argue that its better to call the getter once and store its result in a temporary variable, thus allowing you to freely refactor the implementing class.
As an anecdote, I was once bitten by a change where a getter returned an array, but the implementing class was changed from an array property to using a list and doing the conversion in the getter.
The compiler should optimize either one to be basically the same code.
I recently started a new project and I'm trying to keep my instance variables always initialized to some value, so none of them is at any time null. Small example below:
public class ItemManager {
ItemMaster itemMaster;
List<ItemComponentManager> components;
ItemManager() {
itemMaster = new ItemMaster();
components = new ArrayList<ItemComponentManager>();
}
...
}
The point is mainly to avoid the tedious checking for null before using an instance variable somewhere in the code. So far, it's working good and you mostly don't need the null-value as you can check also for empty string or empty list, etc. I'm not using this approach for method scoped variables as their scope is very limited and so doesn't affect other parts of the code.
This all is kind of experimental, so I'd like to know if this approach could work or if there are some pitfalls which I'm not seeing yet. Is it generally a good idea to keep instance variables initialized?
I usually treat an empty collection and a null collection as two separate things:
An empty collection implies that I know there are zero items available. A null collection will tell me that I don't know the state of the collection, which is a different thing.
So I really do not think it's an either/or. And I would declare the variable final if I initialize them in the constructor. If you declare it final it becomes very clear to the reader that this collection cannot be null.
First and foremost, all non-final instance variables must be declared private if you want to retain control!
Consider lazy instantiation as well -- this also avoids "bad state" but only initializes upon use:
class Foo {
private List<X> stuff;
public void add(X x) {
if (stuff == null)
stuff = new ArrayList<X>();
stuff.add(x);
}
public List<X> getStuff() {
if (stuff == null)
return Collections.emptyList();
return Collections.unmodifiableList(stuff);
}
}
(Note the use of Collections.unmodifiableList -- unless you really want a caller to be able to add/remove from your list, you should make it immutable)
Think about how many instances of the object in question will be created. If there are many, and you always create the lists (and might end up with many empty lists), you could be creating many more objects than you need.
Other than that, it's really a matter of taste and if you can have meaningful values when you construct.
If you're working with a DI/IOC, you want the framework to do the work for you (though you could do it through constructor injection; I prefer setters)
-- Scott
I would say that is totally fine - just as long as you remember that you have "empty" placeholder values there and not real data.
Keeping them null has the advantage of forcing you to deal with them - otherwise the program crashes. If you create empty objects, but forget them you get undefined results.
And just to comment on the defencive coding - If you are the one creating the objects and are never setting them null, there is no need to check for null every time. If for some reason you get null value, then you know something has gone catastrophically wrong and the program should crash anyway.
I would make them final if possible. Then they have to be initialized in the constructor and cannot become null.
You should also make them private in any case, to prevent other classes from assigning null to them. If you can check that null is never assigned in your class then the approach will work.
I have come across some cases where this causes problems.
During deserialization, some frameworks will not call the constructor, I don't know how or why they choose to do this but it happens. This can result in your values being null. I have also come across the case where the constructor is called but for some reason member variables are not initialized.
In actual fact I'd use the following code instead of yours:
public class ItemManager {
ItemMaster itemMaster = new ItemMaster();
List<ItemComponentManager> components = new ArrayList<ItemComponentManager>();
ItemManager() {
...
}
...
}
The way I deal with any variable I declare is to decide if it will change over the lifetime of the object (or class if it is static). If the answer is "no" then I make it final.
Making it final forces you to give it a value when the object is created... personally I would do the following unless I knew that I would be changing what the point at:
private final ItemMaster itemMaster;
private final List components;
// instance initialization block - happens at construction time
{
itemMaster = new ItemMaster();
components = new ArrayList();
}
The way your code is right now you must check for null all the time because you didn't mark the variables as private (which means that any class in the same package can change the values to null).
Yes, it is very good idea to initialize all class variables in the constructor.
The point is mainly to avoid the
tedious checking for null before using
a class variable somewhere in the
code.
You still have to check for null. Third party libraries and even the Java API will sometimes return null.
Also, instantiating an object that may never be used is wasteful, but that would depend on the design of your class.
An object should be 100% ready for use after it's constructed. Users should not have to be checking for nulls. Defensive programming is the way to go - keep the checks.
In the interest of DRY, you can put the checks in the setters and simply have the constructor call them. That way you don't code the checks twice.
If it's all your code and you want to set that convention, it should be a nice thing to have. I agree with Paul's comment, though, that nothing prevents some errant code from accidentally setting one of your class variables to null. As a general rule, I always check for null. Yeah, it's a PITA, but defensive coding can be a good thing.
From the name of the class "ItemManager", ItemManager sounds like a singleton in some app. If so you should investigate and really, really, know Dependency Injection. Use something like Spring ( http://www.springsource.org/ ) to create and inject the list of ItemComponentManagers into ItemManager.
Without DI, Initialization by hand in serious apps is a nightmare to debug and connecting up various "manager" classes to make narrow tests is hell.
Use DI always (even when constructing tests). For data objects, create a get() method that creates the list if it doesn't exist. However if the object is complex, almost certainly will find your life better using the Factory or Builder pattern and have the F/B set the member variables as needed.
What happens if in one of your methods you set
itemMaster = null;
or you return a reference to the ItemManager to some other class and it sets itemMaster as null.
(You can guard against this easily return a clone of your ItemManager etc)
I would keep the checks as this is possible.