Method-Local inner class cannot access local variables because the instance of the method-local inner class may still alive after the method is over. But local variables will vanish once the local method is over.
I learned that method-local inner class can access final local variable, does this mean final local variable still alive after the method is over?
Sort of. Java anonymous inner classes act like "closures," that is, they "close" around the current local state. However, Java only lets these classes close around final variables. If it didn't, the local state of the variable could change, but the version held in the inner class would not, so it would be accessing an "out of date" instance. This could be confusing to a programmer.
Instead, Java requires that mutability be handled by the instance through methods, not variable reassignment. This leads to better clarity and allows for simpler debugging. For more information about why Java does this, see this answer.
Since the class still holds a reference to the variable, the answer to your question is yes, that instance will not be garbage collected until the inner class relinquishes ownership of the variable.
No it doesn't. It means that a copy of the local variable is still alive, in the inner class instance. The 'final' just makes sure the two copies don't confusingly diverge in value.
Related
I know for a fact that static variable is used for all instances of the object whereas the instance variable is used specifically for each instance.
However, what if we declare the instance variable in the beginning and dont touch it in the constructor ? It will act exactly as a static variable right ?
So why bother using both of those ? I'm so confused.
"if we declare the instance variable"
... then it still is an instance variable even if you don't change it in the constructor. As the name says instance variables are for an instance only, i.e. each instance has its own copy which may have the same value. A static or global variable is only one copy that all instances have access to.
Let me make a real world example:
Several people (instances) are in a room and want to get the news.
Instance variables: everyone gets a newspaper and may chose to read it at their own pace or not at all.
Static variable: a TV in the room. Everyone gets the same channel so if anyone switches the channel all others will be affected too.
... and dont touch it in the constructor
Whether you update a variable in the constructor or not doesn't make a variable an instance variable or a global one. It's how they are declared.
Note that you could have instance variables that are changed by other methods only which is perfectly fine in many designs.
Also note that you could change a global variable in a constructor too albeit that wouldn't make much sense in many cases - but there are valid cases.
Static variables can be used without instantiating an object. You can access these without calling class constructor. Instance variables are accessed globally within the class and if you want to use them they have to be public and you must create new object by calling constructor
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This made little sense to me as each thread's stack is confined to that thread alone. So it is already 'threadlocal', right ?
Why then do we need ThreadLocal ? - On further reading, I confirmed my assumption from various sites (a majority of which fail to provide these facts or contradict each other) that this is indeed applicable for static fields.
Which does make sense.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields ? (I came across some sites that say 'ThreadLocal' is "mainly" used for static fields; even https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html uses the word "typically")
I think that this Question is based on a false premise.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This is not what "global" really means. Global really means accessible to the entire program without any qualification. And in fact, Java doesn't have true global variables. The closest it has is "public static" fields ... which are accessible with qualification.
But back to the Question ...
A threadlocal variable is available to a method if two conditions are satisfied:
The method call must be on the correct thread. (If it is on a different thread, it sees a different variable.)
The method must be able to get hold of the ThreadLocal object that effectively "declares" the thread local variable (in any thread).
Does the 2nd condition imply that the "declaration" is global?
IMO, no. For two reasons.
Global variables in the conventional sense have only one instance. A thread local has a distinct instance for each thread.
The fact that the ThreadLocal is accessible to a specific method does not make it accessible to any method. The normal (and good practice) usage pattern for a ThreadLocal is to hold the object reference in a private static variable. That means that methods in the same class can use the corresponding thread local variable instances ... but methods in other classes can't.
Now it is possible to put the reference to ThreadLocal in a public static variable, but why would you do that? You are explicitly creating a leaky abstraction ... which is liable to cause problems.
And of course, you can do what #Radiodef's answer shows; i.e. create a thread local whose instances are only accessible from methods on a specific instance of a specific class. But it is hard to understand why you would want / need to go to that level of confinement. (And it is liable to lead to storage leaks ...)
Short answer: if you don't want your thread local variables to be accessible, restrict access to the ThreadLocal object.
Only local variables are on a thread's stack.* Static variables and instance variables both live on the heap. If we wanted to, we could also just pass a ThreadLocal around by itself without it ever living inside an object or class.
We could view ThreadLocal as a local variable which could be accessible at any point in time.
Normal local variables are destroyed when the scope they are declared in returns, but a ThreadLocal can live anywhere.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields?
We can make one up...
interface Dial {}
class Gadget {
ThreadLocal<Dial> d = new ThreadLocal<>();
}
class Gizmo implements Runnable {
Gadget g;
Gizmo(Gadget g) {
this.g = g;
}
public void run() {}
}
{
Gadget g = new Gadget();
new Thread(new Gizmo(g)).start();
new Thread(new Gizmo(g)).start();
}
Both threads share the same instance of Gadget but has their own local Dial.
Why then do we need ThreadLocal?
The truth is we don't need ThreadLocal very often, if at all.
* Only local variables are on a thread's stack except in the case of a theoretical optimization the JVM is allowed to do where objects can be stack allocated. We would never find out about this if it happened because it would not be allowed to change the behavior of the program. If an object is shared between threads, it's on the heap.
static ThreadLocal<Whatever> threadLocal;
Declares a field that points to an instance of class ThreadLocal. Each Thread has a Map<ThreadLocal<?>, Object> that associates instances of ThreadLocal with the value the corresponding "thread local variable" has for this Thread. That is, each ThreadLocal instance identifies a "thread local variable", and as far as the JVM is concerned, ThreadLocal is a class like any other.
Usually, when we need a "thread local variable", we only need a single one, and therefore create only a single ThreadLocal instance, which is often kept in a static field for convenient access.
If we need a new "thread local variable" for every instance of the host object, we could simply create a new ThreadLocal instance for every host object, and store in an a non-static field. Off hand, I can't think of a case where this is the simplest solution, but we could do it.
Threadlocal is a container for a set of variables each one of which is only available to one thread, ie it provides an instance of the contained class for each thread. So the ThreadLocal object is globally available (spending on permissions) but each instance of the contained class is only locally available to the thread.
This means that it needs to be initialized and destroyed for each thread slightly differently but in all other ways it is the same as any other variable.
Note : The point of destroying instances is to prevent memory leaks or leakage of state between independent invocations on the same thread if threads are being drawn from a pool.
Thread local variables are often used to provide a thread safe option for storage where there is no need for communication between threads. One such example is to define a new scope in CDI where that scope will exist wholly within a single thread (eg you could define an asynchronous request scope).
As such there is no need to restrict it to static or non-static variables as long as it is accessible where it is needed. In a default java environment Static variables are a convenient way of providing such access but in CDI a Singleton bean can provide the same level of access with many advantages.
In the injected singleton case the singleton bean would contain a nonstatic reference to the ThreadLocal and provide services to access the instances contained therein. Both the references to the injected singleton and the singleton's reference to the ThreadLocal would be non static.
Why we can't use access specifiers for variables declared inside method in a Java Class?
Because it doesn't make sense. Variables declared in a method are local to the method; i.e. they can't be accessed outside the method. What would modifying the variable's declaration achieve?
It would make no sense to do so.
A local variable (one declared in a method) is only in scope during that method - what would it even mean to declare that as "public" or "protected"? Only code within that method is going to know about it, and it's not like you're going to differentiate between different bits of code within that method to allow some parts to access a variable and others not.
Access modifiers make sense only when you want to control how other classes use it. How would you like to control accessing a variable within a method by using those modifiers? That would sound absolutely silly controlling access of variables within a method, especially when the variable scope is only within the method. Once the method completes, the variable will have no existence. Even if the variables are allocated memory from the heap, still, once the reference is gone, the memory is available for garbage collection.
There is no sense of applying access modifier as the local variable access scope is restricted to the method scope. Hence there is no meaning of applying access modifier.
class Foo{
public void stuff(){
private String x=2; //compilation error.
}
}
The above code will not compile if we explicitly apply access modifier.
As per the rules of java whatever the variables declared in the scope of method are not accessible outside, which itself means the variables are themselves private, protected and ofcourse we know its default if none specified. so there is no point in declaring a local variable with above mentioned access modifiers. However , you can still use "final" access modifier for the reason that you don't want it to be changed during the course of the method() because of some processing like unwanted reassignment of value to the variable etc.,
Variables that are declared within a method or a block or a constructor are known as Local variables.
Local variables are initialized within the method/block and are destroyed once the method/block execution is completed.
So, specifying the access modifiers for those type of variables doesn't make any sense.
I was reading Code Conventions for Java from http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html#587.
In that, they have mentioned that we should avoid the use of objects to access a class variable or a method and should we use the class name instead.
Avoid using an object to access a class (static) variable or method.
Use a class name instead. For example:
classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //AVOID!
Is there a particular reason for this in terms or performance or something else?
By class variables I assume you mean static variables.
The use of static variables/methods through instance variables should be avoided because it's confusing to the reader. Since you can only use instances to access instance variables, reading a code that calls static methods through an instance can confuse the reader about what's going on.
Image this case, with Thread.sleep, which is a static method:
Thread.sleep(1000);
Since the method is static and we are calling it through the class name, it's intuitive to the reader to deduce that the effect is to put the current thread to sleep.
Now if we did this:
Thread t = new Thread(...);
t.sleep(1000);
Now which thread is put to sleep? The current one "obviously". Someone not knowing about how sleep works might think that the child thread is somehow put to sleep.
I guess it depends on what you want to do.I for one always use the class name to acces a static variable.Being static it doesn matter the way you do it, but i does save some memory usage.
As for nonstatic variables, always use objects.
It is not any different in terms of the bytecode that's produced, so performance is not the issue.
What is the issue is that using a variable to access static members looks as if the reference held by the variable actually matters to what is being accessed. But it does not! In fact even if anObject where null, you would not get a NPE, but it would just call classMethod.
So the principle is simple: when accessing static members, avoid mentioning information (in this case the variable name) that's actually not relevant to the access being made.
I don't know about performance, but clearly another developper looking your code will know at first sight its a static variable/method if you use it with the classname.
I don't think compiler will give different code using a variable though.
it's because.
1.It tells that the variable or method is a static actually.
2.Also, its checked that the object refers to which class. that incurs extra cost.
I'm new to Java having programmed in Delphi and C# for some time,. My question relates to the usage of the "final" keyword on a variable that holds an instantiated class when the variable declaration and instantiation both happen within the scope of the same method. e.g.
private String getDeviceID() {
//get the android device id
final TelephonyManager tm =
(TelephonyManager)GetBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String deviceID = tm.getDeviceId();
// log debug message containing device ID
Log.d(LOG_CAT, "getDeviceID: " + deviceID);
return deviceID;
}
okay so I think I get the fact that "final" variables can only ever be assigned to once and cannot be changed due to the "final" keyword on each declaration, but don't both variables go out of scope when the method exits? and calling the method again will simply reallocate 2 new final variables that once again will go out of scope on method exit?
To me it seems kinda odd to be using the "final" keyword on these variables? unless I don't understand how they impact on local variables within a method's scope?
Can someone enlighten me as to what the impact of "final" is with regard to method scope, or is declaring these particular variables as final just a dumb ass thing that someone did?
final has no effect on scope.
It just prevents the variable from being re-assigned.
It serves as a signal to other developers that these variables will never change, and it prevents you from changing them by accident.
This is particularly useful in longer methods.
final is also required in order to use a variable in an anonymous inner class, since Java does not support true closures.
These variables will indeed be garbage collected as soon as the GC will run when the method exits.
The final keyword is really there as a hint: this variable is instantiated once, you should not touch it in the body of the method itself. Similarly, declaring method parameters final forbids their reuse (which, imho, is a good thing).
Note however that the keyword only affects the object reference: it does not mean that methods on this object reference which modify its internal state will cease to work (typical example: setters).
Another note: when you omit the final keyword, and you don't modify the variable in the body of your method, the JVM is smart enough to optimize this case. So, you may omit it. Whether or not you use it, and where you use it, is a matter of taste/coding style.
And finally, it is good practice to declare public static variables as final: otherwise, anything can modify it! Think string constants etc.
There's nothing special about the scope of a final local variable or parameter.
Declaring a local variable or parameter as final doesn't really do much and is rarely necessary. There are basically two reasons for it:
Some developers believe that anything that doesn't need to be mutable should be immutable. While I agree in principle (immutability is a good thing in many respects), I think that for a language like Java, declaring everything final is going overboard.
If your method contains a local or anonymous inner class and you want any of its local variables or parameters to be accessible to code in the inner class, you have to declare them final. This is a kluge in the Java language; its purpose is to prevent code in the inner class from trying to modify the variables or parameters after they are no longer alive.
They're final to the scope they're in. That's just the way it works.
I imagine the point of making them final in this instance is to prevent future developers from changing them when they shouldn't be changed. It's just defensive coding in this case.
Readability
When it comes to local scope, I find that its usage is variable. That is, some programmers will elect to use it (and abuse it...like me) and some will use it sparingly (e.g. to ensure a class cannot be subclassed, immutability, and etc.).
I find that when working with a group of developers, it's either all, or nothing. Once you start including final modifiers in the local scope, you know that you're hooked and there's not much your team can do (except get you fired...somehow...for being an effective developer).
My perspective
It is a good practice (for better maintenance etc) to make the local variables as final. This is one way of reducing the side effects. Side-effect free code is easy to reason about and hence more readable and easy to maintain.
Overly religious programmers would tell you to mark final on local variables (including method parameters) whenver you can.
In practice nobody does that, including those programmers.
Don't bother.
final is like const in c for primitives and references.