How to control visibility of variables in Java? - java

I can imagine 3 type of visibility for variables (but I think there are more):
Variable is used within a method and any changes of the value of this variable are not visible from outside of the method (so it is local for a particular method).
A variable is local to the class meaning that it is unvisible from outisde of the class. However, any method of the class can easily see and change value of this variable without necessity to give the variable in the list of arguments of methods (so it is kind of global within the class).
Variable can be accessed by "objectName.variableName".
How do I declare these different kinds of variables?

1) Any variable declared in a method is only visible in that method. (method-local). The programmer has no choice in that.
2) Any variable declared with the modifier private is visible only from within instances of the class it is delared in.
3) public variables can be accessed from any class with object.variable; protected variables can be accessed in this way from subclasses only; private variables can be accesses in this way only within instances of the class the variable is declared in.
For detail and reference, see the Java Learning Trail on Sun's website.
However: exposing class members (variables) to other classes is bad practise, and access should be enabled using methods, such as:
public class MyClass {
private int myInt;
public int getMyInt() {
return myInt;
}
public void setMyInt(int newInt) {
myInt = newInt;
}
}

Important to remember: If you declare a variable in a class and don't use any access modifier it will be package-private. That means from other classes within the same package you can reference it with objectname.variable while from classes in other packages you can't.

1: just something like int i; within the method
2: use the private modifier or protected modifier
3: use public

Related

Why is it possible for objects to change the value of class variables?

By Oracle's definition,
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
So this line from the same definition is a bit confusing:
Any object can change the value of a class variable...
So I tried this code and it prints 45 (although I get a warning saying "Static member accessed via instance reference"):
public class Main {
static int value = 8;
public static void main(String[] args) {
// write your code here
Main main = new Main();
main.value = 45;
System.out.println(value);
}
}
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
It's not really that "one object" can - it's just you're in code which has access to that variable, and unfortunately Java allows you to access static members (both variables and methods) as if they were instance members. This ends up with very misleading code, e.g.
Thread t = new Thread(...);
t.start();
t.sleep(1000);
The last line looks like it's asking the newly-started thread to sleep - but actually it'll make the current thread sleep.
This is basically a flaw in Java. The compiler will silently turn code like this into
Thread.sleep(1000);
or in your case
Main.value = 45;
(I believe that in an older version of Java, it would emit code that checked for nullity with the variable you were accessing the static member "through", but it doesn't even do that any more.)
Many IDEs will allow you to flag code like this with a warning or error. I would encourage you to turn on such a feature. If you see existing code like that, change it to use access the static member directly via the declaring class, so it's clear what's going on.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No, static field is accessible for modifications, as long the access modifier allows it.
main.value = 45;
The compiler will read this line at compile-time as:
Main.value = 45;
Being able to create a class with static variables and methods so that those variables and methods are shared by all instances or objects created from the class can be very useful, see When to use static methods.
When sharing a static variable in a class between multiple instances or objects created from the class, the synchronized modifier may be required in order to ensure that if the static variable is being modified by objects in more than one thread, that data integrity is maintained, see What does synchronized mean? and also see How to synchronize a static variable among threads running different instances of a class in java.
The final key word, see How final keyword works is used to determine whether a variable is immutable or not. So if you want to have a class static variable that should be immutable or a constant then you can add the final modifier to the definition. However see Java final keyword for variables which explains that the underlying value for a reference may not be immutable in the sense that functional programming means. See also what is meant by immutable as well as Why final keyword is necessary for immutable class.
You can also use modifiers such as public to determine the visibility of variables and methods in a class, see What does public static void mean in Java.
By using modifiers such as final or private the programmer is able to finely tune the visibility and modifiability of variables in class and objects instantiated from the class.
Litle example how the compiler change the object field access to a class field access.
public class A {
static int foo = 25;
static public void main(String[] arg){
B b = new B();
A a = b;
System.out.println(b.foo);
System.out.println(a.foo);
}
}
class B extends A {
static int foo = 60;
}
The output is:
60
25
It also shows that can be confiusing as it have different behaviour as for object fields.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No. By this definition, that static variable belongs to the class and is modifiable by any instance of the class. There is no implication that when some variable is shared that it should not be modifiable. Use final if you want that.
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
To increment the value in constructor and decrement it in finalizer, for example.
A static variable has a single instance for the whole class that defines it. When an instance is created, an instance of that static variable IS NOT CREATED. There is only one, and that one is freely modifiable by any function without the need for an instance. (unless it is declared final)

Why variables have to be final in anonymous methods and class fields don't [duplicate]

This question already has answers here:
Why are only final variables accessible in anonymous class?
(15 answers)
Closed 9 years ago.
If I had this anonymous method I should declare x variable as final.
private void testMethod (ListField<BeanModel> listField){
final ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();
listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {
#Override
public void handleEvent(ListViewEvent<BeanModel> be) {
loader.load();
}
});
}
However, if loader was a class field, it wouldn't be necessary to declare it as final:
public class testClass{
private ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();
private void testMethod (ListField<BeanModel> listField){
listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {
#Override
public void handleEvent(ListViewEvent<BeanModel> be) {
loader.load();
}
});
//Could I modify loader's reference here, before the method executes?
//loader = null;
}
}
Does anyone know the reason why they guarantee local variables not to change when they're accessed but don't do it for class fields?
Accroding to java docs
An anonymous class has access to the members of its enclosing class.
An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final (Effectively final means that the variable is never changed after it is initialized. Method parameters are often effectually final.)
The reason for this restriction becomes apparent if we shed some light on how local classes are implemented. An anonymous local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee in place, the local class is assured that its internal copies of the variables accurately reflect the actual local variables.
The local variable is allocated in the stack, and it will fall out of scope after testMethod(). Making the variable final ensures that it is ok to just pass a reference to it to the anonymous class. If it was not final, a later assignment to it in testMethod() could change the value later with confusing results. (The user might expect the later assigned value used, but that would be impossible).
A field of the parent class, however can be accessed through the parent reference of the anonymous class, so any later assignments can be handled without confusion.
Anonymous classes get local variables implicitly through constructors. That is they get copies of local vars they use. So if we changed variable value in the main code the anonymous class would not see this change. Declaring local vars final helps avoid this ambiguity.
Have a look at Lambdas and Conjures in java.
An anonymous inner class has no information around it - you have to specify that it is final so you can guarantee its existence.
This could be something to do with the nature of a ListLoader but I am unexperienced with using this library.
I hope I pointed you into the right direction.

private variables in java?

I was watching a tutorial on youtube and the topic was private variables. We usually set variables in java like this:
class hello {
public static void main(String args[]) {
String x;
x = "Hello"
}
}
but in that tutorial, the string type was declared out of the method like this:
class hello {
private String x;
public void apples() {
x = "this is a private variable.";
System.out.println(x);
}
}
As you can see it was not the main method, but i want to ask that do private variables always have to be out of method or what?
I am a beginner so this will be really helpful to know as i don't want to cram up knowledge to prevent confusion and also because it is a matter of fact that people who cram up code never become a good programmer.
do private variables always have to be out of method or what?
That's right. A variable inside a method is a local variable and can not have any access modifiers such as private, public or protected. These modifiers can only be applied to member variables, i.e. variables that are declared in the class scope.
If you think about it, it makes a lot of sense, since local variables can't be accessed by another class anyway. Not even another object of the same class or another method in the same object.
Related question:
What is the difference between a member variable and a local variable?
Cass variables must be declared to be one of the following types:
Public
Protected
Public
In the first example, the variable is local to the function: that is, it's specifically bound to method hello.main().
In that case, it's only accessible within that method function. It's not a class variable, so it doesn't need its access level to be set.
In the second example, the variable is a class variable. When you have a class variable, you can set it to private (can only be accessed by an object of that class), protected (accessed by inherited classes), or public (can be accessed outside of the object). The many methods possible inside the class can then access that class variable.
When you have a variable set inside a class definition, and not inside a method, it is called a "field" or "property" or "attribute." The way you define the accessibility of the field is required since multiple methods within the class can refer to it.
When you have a variable set within any method, it can only be accessed inside of that method, and can't be accessed outside (unless you use a reference pointer or pass it through method arguments).
A private variable in Java is a variable Globally accessible to the class and only to that class (and of course any other methods in the containing class).
A variable declared within a method can be accessed only within the scope of the method. A variable declared inside an if statement is only accessible inside the if statement .... and so on.
Its best to have as little private variable as possible because of performance issues. Lets say you have 100 private variables declared in a class. Your class contains 10 methods and each method utilizes 10 variables. When instantiating an object then your object is created instantiating olso the 100 private variables. If you make you variables local to your methods, then no variable is created on instantiation of the class, and 10 variables are used each time you access a method....
There are also other types of variables in java, to better comprehend you can start from here http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html
I think what's confusing you is the distinction between a local variable (declared in a method), and a member variable (declared in a class, outside of the class's methods).
A local variable exists just while the method that it's declared in is running. It comes into existence at the point that it's declared, then goes out of scope later, when the next } character occurs (other than those that match { characters that aren't opened yet). This effectively means that the variable disappears in a puff of smoke - it can't be used once it's gone out of scope.
But a member variable lives inside an object. That means it gets created when the object is created, and destroyed when the object is destroyed. So it typically lives for a much longer duration than the local variables do. Member variables can sometimes be used by objects other than the object that they belong to; and there are some quite complex rules around when it's possible to do this.
The private modifier on a member variable just means that it can only be accessed by code that's in the class that the object belongs to.
but i want to ask that do private variables always have to be out of method or what?.
Well, It doesn't make sense actually to make a variable private in a method. Because variables declared in a method are stack variables and they have narrower scope than a private one. As they can be accessed only in the method they are declared in and private variables have scope in the whole class they are declared in.
Any variable created with in a scope ( code block bounded inside { } ) is a local variable of that scope; and not accessible out side the block.
Also private variables is term which comes into picture when you talk about classes and define a member which is not accessible outside class.

Why should my local variables be final to be accessible from anonymous class? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Cannot refer to a non-final variable inside an inner class defined in a different method
What is the reason behind the rule of having local variables declared as final in order to access them from anonymous class?
When you access a final variable from an anonymous class, the compiler secretly copies their value into a member variable of the anonymous class. eg:
Runnable foo() {
final int x = 42;
return new Runnable() {
void run() {
System.out.writeln(x);
}
};
}
becomes:
// the actual name is generally illegal in normal java syntax
class internal_Runnable implements Runnable {
final int x;
internal_Runnable(int _x) { x = _x; }
void run() {
System.out.writeln(x);
}
}
void foo() {
final x = 42;
return new internal_Runnable(x);
}
If the variable were not final and were allowed to change, the value cached in the anonymous class instance could go out of sync. This could have been avoided by use of a closure - that is, an object holding the values of all local variables, that both the original function and the new anonymous class instance access. .NET uses closures, for example. However, this can incur a performance hit, and perhaps for that reason, the Java language designers decided not to support full closures.
...when an object of the
anonymous class is instantiated,
copies of the final local variables
and method parameters referred to by
the object's methods are stored as
instance variables in the object. The
methods in the object of the anonymous
class really access those hidden
instance variables.
Thus, the local
variables and method parameters
accessed by the methods of the local
class must be declared final to
prevent their values from changing
after the object is instantiated.
From here.
An anonymous class is a separate class. It has no access to the control flow inside your method. If you would reassign the variable in the anonymous class, you would actually only reassign the anonymous class' copy of the variable. That would be very error-prone, and hence the design choice was made to make it an error.
If you want to work around that, use an AtomicReference.
It's because the anonymous inner object might out-persist its context, which, if it were referring to non-final variables, would then have it talking to things that don't exist any more.

Local variables in java

I went through local variables and class variables concept.
But I had stuck at a doubt
" Why is it so that we cannot declare local variables as static " ?
For e.g
Suppose we have a play( ) function :
void play( )
{
static int i=5;
System.out.println(i);
}
It gives me error in eclipse : Illegal modifier for parameter i;
I had this doubt because of the following concepts I have read :
Variables inside method : scope is local i.e within that method.
When variable is declared as static , it is present for the entire class i.e not to particular object.
Please could anyone help me out to clarify the concept.
Thanks.
Because the scope of the local variables is limited to the surrounding block. That's why they cannot be referred to (neither statically, nor non-statically), from other classes or methods.
Wikipedia says about static local variables (in C++ for example):
Static local variables are declared inside a function, just like automatic local variables. They have the same scope as normal local variables, differing only in "storage duration": whatever values the function puts into static local variables during one call will still be present when the function is called again.
That doesn't exist in Java. And in my opinion - for the better.
Java doesn't have static variables like C. Instead, since every method has a class (or instance of a class) associated with it, the persistent scoped variables are best stored at that level (e.g., as private or static private fields). The only real difference is that other methods in the same class can refer to them; since all those methods are constrained to a single file anyway, it's not a big problem in practice.
Static members (variables, functions, etc.) serve to allow callers of the class, whether they're within the class or outside of the class, to execute functions and utilize variables without referring to a specific instance of the class. Because of this, the concept of a "static local" doesn't make sense, as there would be no way for a caller outside of the function to refer to the variable (since it's local to that function).
There are some languages (VB.NET, for example), that have a concept of "static" local variables, though the term "static" is inconsistently used in this scenario; VB.NET static local variables are more like hidden instance variables, where subsequent calls on the same instance will have the previous value intact. For example
Public Class Foo
Public Sub Bar()
Static i As Integer
i = i + 1
Console.WriteLine(i)
End Sub
End Class
...
Dim f As New Foo()
Dim f2 as New Foo()
f.Bar() // Prints "1"
f.Bar() // Prints "2"
f2.Bar() // Prints "1"
So, as you can see, the keyword "static" is not used in the conventional OO meaning here, as it's still specific to a particular instance of Foo.
Because this behavior can be confusing (or, at the very least, unintuitive), other languages like Java and C# are less flexible when it comes to variable declarations. Depending on how you want it to behave, you should declare your variable either as an instance variable or a static/class variable:
If you'd like the variable to exist beyond the scope of the function but be particular to a single instance of the class (like VB.NET does), then create an instance variable:
public class Foo
{
private int bar;
public void Bar()
{
bar++;
System.out.println(bar);
}
}
If you want it to be accessible to all instances of the class (or even without an instance), make it static:
public class Foo
{
private static int bar;
public static void Bar()
{
bar++;
System.out.println(bar);
}
}
(Note that I made Bar() static in the last example, but there is no reason that it has to be.)

Categories