Is it better to use local or global variables?
Let's say talking about 2000+ lines of android(java) service class, and all service is working on 'request' object and similar shared objects.
If I make everything local(keep inside of function), I need to pass many variables every time, or override same function many times. I need to make sure that objects, and sub objects are not null too.
If I make some variables global(across the class) I can share them, use them across the functions. Which I think will make everything easier.
What are the good sides and bad sides of defining variables inside of function or defining globally. In practice, and in theory(readability etc).
Is there suggested way?
Thank you.
Always prefer local over global. If you need to pass the data in as multiple parameters, so be it. At least then you're explicitly saying what data your function depends on. Having too many parameters is certainly a problem, but offloading some of them as globals isn't the answer.
If you rely on globals, it may not be as clear where certain data is coming from. If the globals are mutable, you'll have a mess on your hands as soon as you start to try to debug a difficult problem since it may not be obvious when certain global variables are being modified.
Note though that immutable constant globals aren't bad. If you have a constant that's needed in many functions (like PI for example), it makes sense to make it global. Immutable constants don't suffer from the drawbacks mentioned above since they can't change.
You wrote a 2000+ lines of service class. You completed the project. Cool ! Now after a month, you got a bug reported and are required to fix it.
Lets go through 2 different cases :
CASE 1
You are back on the service code. You see that the func1() uses globalVariabl1. Okay, but whats its value by now ? How does it change ? Who mutates the globalVariabl1 before it comes to this function ? What have been the sequence of all these mutations ? You would have no idea. It will be quite difficult to figure all this out.
CASE 2
You are back to you code, and see that the func0() fetches something and then passes it to func1(param1) as a parameter. You clearly know what the data is, how does it gets here.
In what case will it be easier to resolve the bug ?
Most of the time, CASE 2 will make it lot easier.
Local variables
Local variables would always help you. Even when you write the code and using local variables, the call statement will itself tell you that this function depends on this particular data. It helps you to be careful about what you are passing around.
Global variables
Global variables are okay when they represent the state of the class/object, or even when they are Constant (which should in general be all UPPERCASE letters). They can also be good when you just need to access the value frequently, and you know that the variable will always be initialised when you use it (for example initialising it inside onCreate())
There are no global variables in Java. You are referring to member variables. The basic rule is that variables should have the smallest possible enclosing scope.
I know the question is already answered and I upvoted Carcigenicate's answer.
To elaborate on his point I would suggest you try Test Driven Development practices. As soon as you start writing your code in conjunction with Unit test you will realize how bad Global variables can be and you will realize that you are writing code that cannot be tested without having to implement unnecessary Dependency Injection.
One more thing. Global variables are a huge mistake any time you start dealing with multiple threads and concurrency. It doesn't sound like you are dealing with that but keep it in mind any time you decide to make a Global variable.
It all depends on the scope of the variable. If you feel that a certain variable will take multiple values by passing through various functions then use local variables and pass them in function calls.
If you feel that a certain variable you need to use will have constant value, then declare it as a global variable.
Related
My question is about making fields static in Java. Should we really do that every time we can do that? For example, the value of the potential static instance doesn't depend on the instance itself and is not going to be changed as long as the state of some instance's changed.
When you declare instance variables, they take up memory for each instance. So if there are going to be 2,000 instances of an object, and you have a 32bit variable, that's 8KB of wasted memory. On the other hand, if it's static, it is only created once for the class, so instead of using 8KB, we use 1B.
Whether or not that matters depends on the situation. Working in an embedded system, I'm going to do everything I can to save that 8KB. On a reasonable desktop, I probably don't care as much.
I guess my question is, are you saying it likely won't change or it won't change. If there's a possibility someone's going to want to change it, or its value will be associated with the state of an instance, it should NOT be static. If it is 100% the same for every instance, I'd say it should be static.
However, I'll always add the caveat, do what seems to make the code most readable and makes the most sense in your situation. Since we're speaking hypothetically, it's hard to say with certainty what you should do in your situation.
Static fields belong to a class, hence shared by all the objects of that class, so memory usage is less... If you want the field to be shared be shared between objects then yes you can do it.. If you declare the field as public and static, then it is globally available for everyone.
Now this has a Problem...
Say you are doing some execution with a static field and that is shared by all the objects... So if any object changes that value then it is changed in all the objects as the field is shared by every object... Which can ruin your execution and program drastically...
Now what i think is, it depends on what you have to do... if it requires to make field static then by all means do that... But prefer making fields non-static due to the problem i mentioned above..
Unless you really have to save memory, either make the field a constant by declaring it static final or leave it as it is.
In my experience, static non-final fields will only get you in trouble because of unforeseen side-effects which are usually very hard to find.
By the fact that you added the following in your question:
For example, the value of the potential static instance doesn't depend on the instance itself and is not going to be changed as long as the state of some instance's changed.
I think you know what you are doing. A lot of people say to not use static, but what they are really saying is, "if you do not know what you are doing, then do not use static." But as long as you understand that the static field belongs to the class and not the instance and hence realize and calculation the ramifications of that, then go ahead and do it.
For example I like to put our log4j Logger's as static final fields. They are final, and named after the class, and do not throw an exception that needs to be dealt with. So in that scenario it is better for the memory footprint to just have one of these Loggers versus a seprate one for each instance.
One of the big issues, and I mentioned it above, is whether the initialization of that static field has a potential exception that must be dealt with. Many times that is the one point the last hurdle that forces me to make a field non-static.
I'd like for efficiency sake to ask the following question. In, for example C you would declare a "global" variable if you wanted to re-use the same variable in functions over and over again without the added cost of converting it to a local variable (as that would require to re-initialize that variable when we call that function again).
In Java I am not so sure what would be best, have a local variable and re-initialize it over and over (maybe the optimizer is smart enough to remember it?) or declare it as a private variable separately inside the class? My gut tells me the latter should be better (and that is what I am currently doing) but I am not entirely certain that is the case.
Of course please exclude the multi-threading scenario where atomicity would be a thing.
I think that answer might help you. He wrote a micro-benchmark for determine the access speed of local and instance variables.
The result showed that local variable accesses are about 1% faster than instance variable accesses (even if both point to the same object).
Do not try to tune performance on such a low level. The performance of the resulting code depends heavily on the compiler anyways, but such a small "improvement" will not have any significant increase at all, as you are only talking about assigning a simple value to a variable, which does not take significant time to do (if we are talking about complex objects being created every call, that is obviously different, but your question was about initializing variables, so I answer that).
However, having a variable that is only relevant for a single function as a field of a class really hurts the readability and self-expression of your code, as the field is not relevant for an instance of that class at all.
Conclusion: If a variable is a local function variable, put it into the local function scope. If it is a field, put it as a field. Do not try to tune performance that way.
You cannot directly convert all you local method variables to instance variables. You ll break your code if you do so.
Instance variable are for specific purpose - which defines the state of an object. What you are asking can be solve by using static variables(probably final also - depending on the situation). If you use static variables - it ll be available for all the objects you create. But it will compromise with the thread safety as any object can modify it.
Private variable are accessible within the class while local function variable are accessible only within the function.
I am creating a game and I have all of my data encapsulated which obviously means if I want to get something from an instance of that class, I have to call a getter method. I have a rendering loop that is being called many times a second. I am having to use multiple calls to the same getter method in order to grab a single field from an object and do multiple things with it. Would it be better to just store an extra reference to the object that I am constantly grabbing in my class that needs it? In this case I could grab it in the constructor and be done. Does this make sense? Thanks a ton.
I agree with the other posted answer that there is no performance difference.
However, I think the discussion in that answer about readability and best practice both misunderstand the OP's question. He is not asking if he can eschew best practice and not use getters. He's asking if he can/should create a local reference to the retrieved object rather than calling the getter on every line, and in my world that is standard practice and is indeed much more readable.
Consider first:
doFooThings(service.getFoo());
doBarThings(service.getFoo().getBar());
doBazThings(service.getFoo().getBar().getBaz());
doMoreBazThings(service.getFoo().getBar().getBaz());
doOneLastAmazingBazThing(service.getFoo().getBar().getBaz());
Compare to:
Foo myFoo = service.getFoo();
doFooThings(myFoo);
Bar myBar = myFoo.getBar();
doBarThings(myBar);
Baz myBaz = myBar.getBaz();
doBazThings(myBaz);
doMoreBazThings(myBaz);
doOneLastAmazingBazThing(myBaz);
The second version is much more readable, especially in the real world when there is a lot more noise and indentation in the code, it is much easier to read terse lines reference local vars that are descriptively named, rather than seeing the same getter call appear a dozen times in row.
Would it be better to just store an extra reference to the object that I am constantly grabbing in my class that needs it?
No.
Especially since you say your code is called often, the JIT will kick in. It will certainly see that the getter call can be replaced by a more simple load.
Don't underestimate the JIT!
I'm a beginner with java programming and I have a simple question:
When should I use return values? I understand the meaning and what I can do with it. But I wonder if I shouldn't always make global variables to work with.
Can you guys tell me when I should choose which option?
The answer is GLOBAL values should be avoided as much as possible. The reason is global variable persists until the entire lifetime of that program. The GC (Garbage Collector) does not collect them until the program finishes(there may be some exceptions to this). But in contrast to this, local variables are eligible to be collected as soon as they fall out of scope. So the GC can collect them efficiently which leads to good memory usage.
So,
Generally, try to avoid using 'global' variables unless you have good reason to do so (e.g. the variable's contents are needed by more than one method in your sketch). This will help reduce the chances of inadvertently changing the contents of them in your code. So your second choice is one to avoid.
Some key points why NOT to use global variables:
It violates DATA ENCAPSULATION principle.
Lifetime is for whole program.
Messed up code if not carefully implemented
For example, if you have two copies of your program running in the same VM, will they share the static variable's value and mess with the state of each other.
Static variables represent state across instances which can be much more difficult to unit test. This is mainly because it is more difficult to isolate changes to static variables to a single test
This one is bothering me for a while now :)
Suppose we have a variable - why is writing a Set function better practice than simply modifying variable's data (and setting the variable to be public instead of private)?
It's less coding that way and I can't see any "security" issues.
Sometimes when setting a variable, you may want to do something else with the given value other than instantly place it in the class's variable: for instance, you may want to validate it or update another value that is related.
Basically, it lets the class which owns that variable control what can be done to it, and the specific series of events that occur when it is altered.
It also needs to be mentioned that it is not always better to use "set" methods. Blind compliance with patterns may lead to overcomplicated code. If class acts as just simple (really simple) data container, then public access is often acceptable. In example, look at java.awt.Rectangle or at java.awt.Point classes.
It all has to do with object orientation and how strict you are in that doctrine. If you strictly follow all the guidelines, it is bad to directly use methods and identifiers from one class, by the other. Technically there is no objection.
This discussion is the same as the static - no static discussion. The (self proclaimed) guru, found that sacrilege, but you put your computer no obstacle in the way, if you put your whole program is static.