I always read on the web that global variables are bad, and I understand that they are bad because each function has access to them and if each function in the application modifies the global variable, in a large application, it can become very difficult to trace the state of this variable at a particular point in the code.
But my question is this, if I have a variable that each function is going to need to use anyway, isn't it better to declare it as global? instead of having to instantiate my variable every time inside each function?
Also, when should I use global variables as opposed to local variables?
Every variable represents some real or imaginable entity. If you are sure that entity is unique, then it's OK to have static variable for it. For example, screen/keybord/mouse devices are represented with static variable of type java.awt.Toolkit (accessible via getter).
But such cases a rare. Usually, programmer thinks of single instance of entity, and declares a static variable for it, and then a need for another similar entity arise, which ends in laborious refactoring.
This is all about memory utilization while code is running.
You always try to keep less number of object into the memory while code running.Object with less scope(method scope) your object will live less in memory hence good memory utilization. So need to keep variable as less scope as it is necessary.
But your statement for global variable is not fully correct as in java we have access modifier (public,private,default etc) and if any global variable(class variable) has private modifier then it cannot be modified by outside the class.
Related
In C/C++ we use static local variables for maintaining a method's state. But why it is not supported in Java?
Yes, I can use an static field for this purpose. But isn't it a bit weird to create a field for maintaining only one method's state?
You have found the only solution.
Java dropped a number of complexities from C++, and this was one of them.
Static variables scoped to a function do nasty things to you in concurrency (e.g. strtok is a famously nasty one to use with pthreads, for exactly this reason).
In general, what you want is an object with state. The function in question should then have an object-level variable. Then you can create instances that each maintain state.
Much easier to understand/maintain/etc.
If you truly need to maintain state as a singleton, then static fields are it.
The Java language spec doesn't seem to defend the omission of variables that correspond to C static variables.
Hiding state in class methods has a few drawbacks when seen from a Java perspective. Generally the existence of a function-level static variable isn't the sort of implementation detail that you'd want to expose outside of that function.
But the method's state is actually part of the class's state, and method-level static variables would have to be serialized / deserialized any time the object is persisted. This might not sound common, coming from a C background, so I'll note a few common examples.
Application server clusters can pass user session objects between nodes in order to provide fault tolerance.
JAXB could be used to marshall an object into an XML document
JPA can be used to persist object state to a database
If the variable's value is worth saving when the object is persisted, then there's a good chance that code outside of that class will need to reference that value. And suddenly that means defining access levels -- is a static variable in a public method automatically public? Or would a programmer have to declare it so?
We also have to think about extensibility. Would derived classes be required to implement the same static variable? Or would there be a reference to the variable from the function in the base class?
It's more likely that the C method that would use a static local variable would be a good candidate for a class in Java. It has state and hopefully exists for a single purpose. There's little drawback to encapsulating the functionality into an object, and it makes for a cleaner separation between transient values (such as local variables) and more long-term state.
Some of the other answers show why you might not want to have this. But you can also ask why from a historical perspective.
To answer this you have to start to see why C does have static local variables. C has much fewer means than Java and C++ to limit the scope of a variable, the only options for static data are 'inside the file' and 'everywhere'. So this provides an extra layer, to limit the scope.
An important aspect of C++ is compatibility with, so it is allowed in C++ as well. But it doesn't need local static scope as much anymore, because there are many other means to limit scope of static data. The use is not popular in (modern) C++.
Java merely takes a lot of inspiration from C/C++, it didn't have to worry about backwards compatibility, so it could be left out.
Perhaps because methods are not objects in Java; so maintaining their state as you said make not much sense and I guess you'd have to create a new concept in the byte code for that; use an object as Tony K. said.
instance methods are invoked by the instance(objects) of the class . Static things belongs to the class not to the object that's why local variables are not static.Instance variables are static and they can also initialized at the time of class loading by static blocks.
enter image description here
for more information please visit :- https://www.youtube.com/watch?v=GGay1K5-Kcs&t=119s
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.
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 actually have a quick question which I cannot find an answer to.
I am VERY persistant that my Android/Java application eats up the least amount of RAM as possible as it helps the user experience.
With that being said my question is focused on field variables and the garbage collector.
My application will start up and I have a list of set field variables (hardcoded). Now for the sake of readability I have chosen field variables. If I wish to make a quick change I change the value instead of me looking through my code to see when the variable is actually used.
My field variables in this case are only used ONCE, when the application is loaded for the first time.
Does the garbage collector remove this variable or must I set it null manually. I know a simple int value isn't much to cry over, however I am curious as to the garbage collector.
The object which contains the field will always be in use (it will be an Android ViewPagerAdapter in this case).
Field variables are strong references; as long as that class object is around, the field variable must remain accessible. If you're only using them in one method, it'd be (marginally, slightly) more efficient to only keep them in scope for the run of that method.
In general you don't need explicitly set fields to null, however if you really concern about performance/memory avoid creating fields instead go for local variables i.e. Convert fields to local variable to method if possible and Avoid creating unnecessary fields if they used only once.
Best I would suggest for you is please refer to Android Best practices documentation for app performance improvement
http://developer.android.com/training/best-performance.html
http://developer.android.com/training/articles/perf-tips.html