JLS 8.1.3 gives us the rule about variables which are not declared in an inner class but used in the class.
Any local variable, formal parameter, or exception parameter used but
not declared in an inner class must either be declared final or be
effectively final (ยง4.12.4), or a compile-time error occurs where the
use is attempted.
An example:
class A{
void baz(){
int i = 0;
class Bar{ int j = i; }
}
public static void main(String[] args){
}
}
DEMO
Why was the code compiled? We used the non-final local variable in the inner class which was no declared in there.
Variable i defined inside method baz is effictively final because value of variable i is not modified elsewhere. If you change it
void baz(){
int i = 0;
i = 2;
class Bar{ int j = i; }
}
The code will fail to compile because variable i is no longer effictively final but if you just declare the variable i and the initialize it in another line, the code will compile because the variable is effictively final
void baz(){
int i;
i = 2;
class Bar{ int j = i; }
}
i is effectively final, since it is never modified. As you yourself quoted the JLS, the inner class may use effectively final variables.
Because i is effectively final as it is not changed in baz.
Related
What is the problem with below code?
class test {
static int a;
a=10;
}
If I'm writing like this (as above), I'm getting a compile time error.
class test {
static int a=10;
a=4;
}
For the second one, I'm not getting any error.
Neither of your examples should compile.
a=10;
is a statement, which is not valid directly inside a class declaration. You can only put the following directly inside a class:
Member declarations (member/static variable declarations (like static int a;), methods, nested classes and interfaces);
Static and instance initializers;
Constructors.
You need to put a statement inside a block, for example a static initializer:
static int a;
static {
a = 10;
}
which is equivalent to:
static int a = 10;
You need to use a static block of statement to do an assignment on an other line (outside a method)
class test {
static int a;
static { a=10; }
}
a=4; must be done in a valid scope
either a method or a constructor...
this line is valid instead
static int a=10;
because java allows youto declare and initialize in one statement!
If you want to initialize a after defining it as a null int, you can only do that in a function, because it is static.
must be initialized inside static block or init block or in constructor.
you can only initialized your member variable after declaration inside a function or block because it is static you should use static block
What you are currently doing is declaring a variable in a class decleration, which is not valid. Looking at this neither of your examples should give you any good result.
In a class declaration you can however initialize a variable:
static int a;
Then if you want to work with it you would have to create a method first (if you are not aware of this I would strongly advise to watch some youtube tutorials or read books about this topic) :
public void foo(int a){
a = 6; //Here you can play with your variables and change them
}
In class declararions you can: declarations methods, initializers and constructors. (there is a bit more you can do, however I would have a look at these points before diving in too deep).
Furthermore it seems that you are not aware what a static variable or a static method does, I think the following posts will help you with that:
difference between 'static int' and 'int' in java
What are static method and variables?
I hope I could help and have fun learning Java
Because for static memory allocated at the time of class loading
so we need do like this
class test {static int a =10;
public static void main(String args[]) { a=12 output(test.a (or) a);}}
A Java class body is should contain declarations and declaration with an initializer, not the standalone statements. Let's unwrap your requirement of initializing a static variable.
Static variables should not be initialized inside methods as these variables belong to the class. But they can be initiated inside the constructor.
public class Example {
static String name;
static int age;
Example() {
name = "James";
age = 34;
}
public static void main(String args[]) {
new Example();
System.out.println(Example.name);
System.out.println(Example.age);
}
}
Now the output will be :
James
34
If new Example(); is not called then the output will be :
null
0
This is because the static variables are initialized with an object creation and for each Example object name and age will be overwritten with the same value. But at least one object needs to be created for name and age to be initialized.
But if you declare a static and final instance variable, we cannot initialize that in the constructor, it is mandatory to initialize static and final variables at the class level. We can initialize while declaring the variable or using a static initialization block. This runs before the main() method in Java. Hence when the main() method is loaded this static variable will be initialized and the compiler will not throw any errors.
static final int name = "STRING";
static final int age;
static {
age = 10;
}
Putting all these things together,
A static variable can be initialized,
When declaring.
Inside a constructor.
Inside a static block.
A static final variable can be initialized,
When declaring.
Inside a static block.
A final variable can be initialized,
When declaring.
Inside a constructor (If you have more than one constructor in your class then it must be initialized in all of them).
In C++(prior to C-11), we needed to initialize the variables outside the Class either through constructors or some methods. What's happens in Java?
Can a Variable be initialized inside a Class in Java?
Yes, like this:
public class MyClass {
private int myVariable = 10;
}
What about Static Variable? If yes, then what's the use for Static Block?
Yes, static variables can be initialized in the class as well:
public class MyClass {
private static int myVariable = 10;
}
Static blocks are used when you want to initialize a static variable, but one line is insufficient. For example:
public class MyClass {
private static HashMap<Integer, Integer> myMap;
static {
myMap = new HashMap<>();
myMap.put(10, 20);
myMap.put(20, 40);
}
}
c++ v/s Java:
Common- both OOP language
difference- c++ is not purely object oriented language, but Java is purely oop language.
Classes are blueprint(like a general map) which defines some attributes/properties(Member variables) and behavior(member functions) of a object of that class.
Class is just a imagination before creation of a object.
Object is real time entity that has physical existence in real world or in simply it's a implementation of class.
Classes in java:
class class_name
{
member variables;
member functions;
};
Ex.
class A
{
int a;
void funct()
{
//body
}
}; //defination is closed with semicolon
but,
classes in java:
ANSWER to ur quesion:
class class_name
{
member variables; //still we define the attributes in class that may be static or non-static
member functions;
};
Significance of static variable:
static variable is alloacated the common memory in ram for all the objects of that class and operation perform by any object on static member is reflected to all other object's static member because of common(same) memory.
significance of static method(functions are called methods in java): static method of a class is a method which is called without creating the object of that class.
In java, main() method is declared as static because after execution of program main() method is called without creating the object of class.
kernal of OS calls the main() method.
Can a Variable be initialized inside a Class in Java?
Yes.
class TestClass {
int abc = 0;
static int def = 1;
}
What about Static Variable?
Yes, you can. Same Example as above.
But this won't be initialized every time an object of the class is created.
TestClass ob1 = new TestClass();
ob1.def = 2; // Always use the class name to access static variables. This is just an example.
TestClass ob2 = new TestClass();
System.out.println(ob2.def); // Output : 2
PS : Always use the class name to access static variables. This is just an example.
What's the use for Static Block?
If the initialization of static variables is complex, then you can create a static block and initialize those variables there. Here is a good reference for the same.
class TestClass {
int abc = 0;
static int def = 1;
static {
int x = 100;
int y = 20;
def = x - y + 10;
}
}
If you wat to initialize the variable you can create something like
public class Animal
{
int age = 21;
static int roll = 23;
}
But remember the difference between instance variables and static variables,
int age - this variable is created for each object you create
static int roll - this variable is created only once and is one for every other object.
What is happening in the compiler when we do forward referencing methods, how does it assign the value of another variable which is not declared? And can we use that inside methods? But why can we not use the variable in static blocks? For example,
public class Forward {
static int i = test();
static int test() {
System.out.println(j);
j = 20;
return j;
}
static {
System.out.println(j);
j = 20;
}
static int j;
}
If we assign the value directly like:
int i = j;
int j = 10;
Why does this code not compile? How is it possible only with methods? How does the compiler compile the forward references internally? Is the declaration happening first for all the variables and initialization happening next for all at a time or one by one? Explain it in detail.
JLS Section 8.3.3 states that 4 criteria must all be met if the forward-usage of a static variable will be considered a compile-time error:
The declaration of a class variable in a class or interface C appears textually after a use of the class variable;
In other words, obviously, it must be a "forward declaration": you use it before you declare it:
// Maybe not OK to use j here.
static int j;
// OK to use j here.
The use is a simple name in either a class variable initializer of C or a static initializer of C;
You can make a forward reference to the variable if you qualify its name:
static {
System.out.println(j); // Error on this line...
System.out.println(Forward.j); // ...but not this line...
System.out.println(org.whatever.Forward.j); // ...or this line...
}
static int j;
This criterion only applies to variable or static initializers. This answers the specific question of why you are not getting a compiler error when referring to the static variable in a method.
However, let's just finish things off...
The use is not on the left hand side of an assignment;
Note in this code:
static {
System.out.println(j); // Error on this line...
j = 20; // ...but not this line.
}
static int j;
You can't do anything except assign the variable, even if you reverse the order of the lines (you can't assign and then print it).
C is the innermost class or interface enclosing the use.
The following code would be fine:
class Forward {
static class Inner {
static {
System.out.println(j);
}
}
static int j;
}
The compiler says illegal modifier for parameter i.
Please tell me what I'm doing wrong. Why can't I use a static variable in a Java constructor?
class Student5{
Student5() {
static int i = 0;
System.out.println(i++);
}
public static void main(String args[]){
Student5 c1 = new Student5();
Student5 c2 = new Student5();
Student5 c3 = new Student5();
}
}
Because of where you are declaring i:
Student5(){
static int i=0;
System.out.println(i++);
}
the compiler treats it as a local variable in the constructor:
Local variables cannot be declared as static. For details on what modifiers are allowed for local variables, see Section 14.4 of the Java Language Specification.
Judging from what the code appears to be trying to do, you probably want i to be a static member of Student5, not a local variable in the constructor:
class Student5{
private static int i = 0;
Student5(){
System.out.println(i++);
}
. . .
}
If you want to declare static variable then declare it outside of the constructor, at class level like this -
public class Student5{
private static int i;
}
You declaration of static occurred at your constructor which is a local variable and local variable can not be static. And that's why you are getting - illegal modifier for parameter i. And finally for initializing static variable you may use a static initialization block (though it's not mandatory) -
public class Student5{
private static int i;
static {
i = 5;
}
}
This is how the language was designed.. What if you wanted to have another int field named i in the constructor?, then which i should be considered?. Also, static fields are initialized before the constructor is called i.e, during class initilization phase. A constructor gets called only when a new instance is created.
Imagine what would happen (supposed to happen) if you load and initialize a class but not create a new instance.
Static variables are variables that can be referenced without having an instance of the class. By defining one instead of a constructor, which is called when you create an instance of the class, you are contradicting yourself. Either make it defined without having an instance (outside of the constructor and static) or make it specific to an instance (inside the constructor and not static).
You might want to rethink what you are actually trying to do and if you really need a static variable.
If I have:
class A
{
void foo()
{
int a = count;
}
void bar()
{
int a = c; // here ERROR
int c = 10;
}
private int count = 10;
}
here in foo count is used without problem also if it's declared after the use.
The same is not true in method bar where the variable c must be declared before its
use.
Which are the class scope rules? How they differs from method scope rules?
P.S.
My doubt is because the common scope resolutions rules:
When the compiler find count it should try to find it "back" to its
use but back there is Class A... so maybe private int count is "hoisting" at
beginning of Class A?
Imagine that you were a compiler, and you get to the line:
int a = c;
Won't you get angry and ask yourself "What is c"? The order is important1.
1count doesn't make a problem because it's a class member, it's known in the whole class. You can place class members in the beginning of the class, or at the end.
count is declared in the class while c is declared in the method
While compiling, the class would find count in the class.
class A
{
void foo()
{
int a = count;
}
private int count = 10;
}
is equal to put count anywhere in the class, as it is a class member and can be found in the class everywhere.
while in your case of
class A
{
void bar()
{
int a = c; // here ERROR
int c = 10;
}
}
c is not defined before use, as c is a local variable in a method.