I have a class in that I need two variables one is a static one another one is Non-static. What my problem is when we declaring two variables, can we declare them with same name?
Why I ask this question is the static variables and non-static variables are stored in two different areas (static variables in Method area and non-static(instance) variables in heap area).
So, what happens if I declare them with same name? If it is wrong, what is the reason?
No, you can't do the following:
public class X{
int a;
static int a = 10; //Illegal
public X(int a){
this.a = a;
}
}
The reason is that both as are in scope for an instance of x. For:
X x = new X(5);
x.a; //were the static field with name a legal, this refers to both 5 and 10.
it is unclear which version of a is being referred to. Thus to prevent confusion it is illegal.
You can have a variable inside of your method that has the same name as a class-scoped variable. In general, the variable in your method has priority over the class-scoped variable when the variable name is referred to from inside of that method. To be more clear in your code and to make sure you're accessing the correct one, use the this keyword to refer to the variable inside of the method and use the super keyword to refer to the class-scoped variable.
Related
I am learning Java and I understand that you cannot name a variable declared within an inner scope the same name as a variable declared in an outer scope as shown below
public class Practice {
public static void main(String[] args){
int x = 10;
if (x == 10){
int x = 10;
}
}
}
However, I noticed that the following is not illegal
public class Practice {
int x = 10;
public static void main(String[] args){
int x = 10;
if (x == 10) {
}
}
}
Is this not a variable that is declared twice??
Is this not a variable that is declared twice??
No, it is not. Because they both are in different scope. x outside of main function has class level scope while x inside of main has method/function level scope.
It is legal for 2 variables in different scope to have same name.
Please DO read §6.3. Scope of a Declaration from JLS. Below are few of the statement from that section.
The scope of a declaration is the region of the program within which
the entity declared by the declaration can be referred to using a
simple name, provided it is visible (§6.4.1).
A declaration is said to be in scope at a particular point in a
program if and only if the declaration's scope includes that point.
The scope of a local variable declaration in a block (§14.4) is the
rest of the block in which the declaration appears, starting with its
own initializer and including any further declarators to the right in
the local variable declaration statement.
There are lot of concepts related to scope like shadowing, so do read §6.4. Shadowing and Obscuring.
JLS is the best place to learn what is allowed and what is not allowed in Java. Feel free to read sections there.
In the second case when x is declared outside the method, it is an instance variable of the class Practice. Within the method, scope of x(declared inside main) is limited to the main method.
In the first case when you declare x within the method, you cannot declare it inside if because it is already declared in the scope of the method outside if.
The first code snippets shows the variables are in method's scope. So two variable are belonging to same method which is not allowed.
But in the second example one variable is on instance level and the other one in method's scope, so there is no duplicate. In the second example if you want to access the instance variable, you have to do it using this.x.
Check more on scope and lifetime of variables here
http://www.javawithus.com/tutorial/scope-and-lifetime-of-variables
Why can you have a duplicate variable name in java for a variable outside of a method?
It is not illegal because it is allowed by the Java Language Specification. (Yes ... circular explanation)
As with all such questions, we cannot tell you for sure why it is allowed, because the Java language was designed behind closed doors. However, a couple of possible reasons are:
Java was originally designed to be "palatable" to C and C++ programmers, and this is a case where doing it differently (banning shadowing) would have caused objections.
A lot of people actually like it that they don't have to think of different names for variables; e.g.
public class Foo {
private Bar bar;
public Foo() {
Bar bar = new Bar();
this.bar = bar;
}
}
Admittedly, there is a downside. Sometimes, people mistakenly declare local variables that shadow instance (or static) variables. Particularly newbies :-)
Is this not a variable that is declared twice??
No. It is actually two >>distinct<< variables. Both exist. Within the method, the local declaration of x shadows the instance declaration of x. But you can still refer to the latter as this.x.
I didn't understand this part:
Instance variables can be accessed directly by calling the variable name inside the class. However, within static methods (when instance variables are given accessibility), they should be called using the fully qualified name. ObjectReference.VariableName.
Can you give an example please ?
Static methods are methods that are called without a reference to an instance of that object. So instance variables cannot be called statically, as each instance will have its own values. So in a static method, you need a specific instance of an object in order to know which value of the instance variable you are trying to use.
The difference is how you access these variables:
class myClass {
public static int staticVar;
public int nonStaticVar;
//Constructor initialises both
}
Static approach:
int otherVariable = MyClass.staticVar;
As you can see, for the static variable you do not need to make an object to access it. Note that you can imagine a static variable to have the trait "once per class", which means, that you can not have 2 versions of staticVar.
Non Static (instance variable):
MyClass instanceOfMyClass = new myClass();
int otherVariable2 = instanceOfMyClass.nonStaticVar;
To have 2 versions of nonStaticVar you can simply make 2 objects and give this variable different values in the 2 objects. Note that in this case you have to make an object.
For example
Class Moon{
int a;
void mango()
{
a=9; // put 9 in instance variable "a"
}
void orange()
{
int a; // declare local variable with same name as of instance variable
}
}
How this is possible that we can modify the value of instance variable inside method and also we can declare the local variable with same name as of instance variable?
When there is an instance variable and a local variable you can use the instance variable with this.a and use the local with just a.
Common use:
public void setA(int a) {
this.a = a
}
Modifying instance variables from within methods is:
prescribed by the java language specification, and
pretty much necessary: that's how object-oriented programming works.
(I mean, if you could not modify an instance variable from within a method, then where would you modify it from?)
If you want a particular instance variable to not be modifiable from within methods, then you must mark it with the final keyword, like this: final int a; --you will still be able to initialize it from the constructor.
Declaring a local variable with the same name as an instance variable is perfectly valid java; however, it is not advised, and that's why you can usually configure your IDE to issue a warning when you do that. Actually, if your IDE is not giving you a warning, then this may mean that you are not compiling with enough warnings enabled. Always enable as many warnings as you can.
I am learning Java and I understand that you cannot name a variable declared within an inner scope the same name as a variable declared in an outer scope as shown below
public class Practice {
public static void main(String[] args){
int x = 10;
if (x == 10){
int x = 10;
}
}
}
However, I noticed that the following is not illegal
public class Practice {
int x = 10;
public static void main(String[] args){
int x = 10;
if (x == 10) {
}
}
}
Is this not a variable that is declared twice??
Is this not a variable that is declared twice??
No, it is not. Because they both are in different scope. x outside of main function has class level scope while x inside of main has method/function level scope.
It is legal for 2 variables in different scope to have same name.
Please DO read §6.3. Scope of a Declaration from JLS. Below are few of the statement from that section.
The scope of a declaration is the region of the program within which
the entity declared by the declaration can be referred to using a
simple name, provided it is visible (§6.4.1).
A declaration is said to be in scope at a particular point in a
program if and only if the declaration's scope includes that point.
The scope of a local variable declaration in a block (§14.4) is the
rest of the block in which the declaration appears, starting with its
own initializer and including any further declarators to the right in
the local variable declaration statement.
There are lot of concepts related to scope like shadowing, so do read §6.4. Shadowing and Obscuring.
JLS is the best place to learn what is allowed and what is not allowed in Java. Feel free to read sections there.
In the second case when x is declared outside the method, it is an instance variable of the class Practice. Within the method, scope of x(declared inside main) is limited to the main method.
In the first case when you declare x within the method, you cannot declare it inside if because it is already declared in the scope of the method outside if.
The first code snippets shows the variables are in method's scope. So two variable are belonging to same method which is not allowed.
But in the second example one variable is on instance level and the other one in method's scope, so there is no duplicate. In the second example if you want to access the instance variable, you have to do it using this.x.
Check more on scope and lifetime of variables here
http://www.javawithus.com/tutorial/scope-and-lifetime-of-variables
Why can you have a duplicate variable name in java for a variable outside of a method?
It is not illegal because it is allowed by the Java Language Specification. (Yes ... circular explanation)
As with all such questions, we cannot tell you for sure why it is allowed, because the Java language was designed behind closed doors. However, a couple of possible reasons are:
Java was originally designed to be "palatable" to C and C++ programmers, and this is a case where doing it differently (banning shadowing) would have caused objections.
A lot of people actually like it that they don't have to think of different names for variables; e.g.
public class Foo {
private Bar bar;
public Foo() {
Bar bar = new Bar();
this.bar = bar;
}
}
Admittedly, there is a downside. Sometimes, people mistakenly declare local variables that shadow instance (or static) variables. Particularly newbies :-)
Is this not a variable that is declared twice??
No. It is actually two >>distinct<< variables. Both exist. Within the method, the local declaration of x shadows the instance declaration of x. But you can still refer to the latter as this.x.
Is there a difference between assigning values to variables outside of any method, and assigning these values within a constructor?
Looking at Oracle's Java tutorial, they have:
public class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
is this any different from saying/why didn't they just say:
Bicycle(){
int cadence = 0;
}
If you declare the variable in your constructor, it will be local to the constructor and not visible anywhere else in your class.
If you declare a variable inside a constructor, this variable can only be accessed inside this constructor. But, you can create a variable on your class, and access it on your constructor or method.
Well if you define a variable in a constructor, it is local to the constructor. But a variable in the class is part of class' state.
But if you mean:
class A {
int i = 1;
...
}
vs
class B {
int i;
B() {
i = 1;
}
...
}
the difference is: in the first case, the default value of i is 1, in all instances, but in second case the default value of i is 1 if the shown constructor is called, maybe in other constructors other default value be something else (or 0 if nothing is assigned to i).
When you create object instance, global variables will be initialized. You can (but not have to) change some of them in constructor.
I think you mean
Bicycle() {
cadence = 0;
}
In the constructor : it will be Local variable
Java contains the following types of variables:
Instance Variables (Non-static fields): In object oriented programming, objects store their individual states in the "non-static fields" that is declared without the static keyword. Each object of the class has its own set of values for these non-static variables so we can say that these are related to objects (instances of the class).Hence these variables are also known as instance variables. These variables take default values if not initialized.
Class Variables (Static fields): These are collectively related to a class and none of the object can claim them its sole-proprietor . The variables defined with static keyword are shared by all objects. Here Objects do not store an individual value but they are forced to share it among themselves. These variables are declared as "static fields" using the static keyword. Always the same set of values is shared among different objects of the same class. So these variables are like global variables which are same for all objects of the class. These variables take default values if not initialized.
Local Variables: The variables defined in a method or block of code is called local variables. These variables can be accessed within a method or block of code only. These variables don't take default values if not initialized. These values are required to be initialized before using them.
Parameters: Parameters or arguments are variables used in method declarations.
The constructor is like any other method. Variables that are declared inside it are available only within it, and they'll get destroyed when you go out of scope.
The difference in this case is that you are not only assigning the variable in the constructor (in the second case). You are also declaring it there. Thus, the variable is local to the constructor and not visible from outside.
I think your question is: If we can give a default value to the variable(of a class) directly, why to give it inside a constructor instead. If that's the question, then I think its because the values in the variable would be available even when the objects are not initialized which is not a healthy practice and does not make much sense. Instead, giving values inside a constructor would not only be hidden but would also obey oops rules for java.