Automatic variable assignment? - java

Newbie question:
I have two classes:
class A {
public static void main(String...args){
B b = new B()
System.out.println(B.firstVar); // 0
}
}
class B {
public int firstVar;
}
Why does it print 0 when no value was assigned to firstVar ?

0 value is the default value for the int type.
here are some other default values:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

First thing There are two error in your code
One is missing semicolon:
B b = new B()
Second is trying to use non-static member with class name
System.out.println(B.firstVar);
It should be
System.out.println(b.firstVar);
Answer to your question: When a constructor is called it initializes member variable/ properties of class to respective type default values.
Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
String (or any object) null
boolean false
That's why even without initialization it prints 0
Note: Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable.

When you don't set anything to the variable, it is assigned a zero by default (in case of int)

Thats the way Java initilializes variables.
For example int is initialized with 0 and Objects with null
Object obj; // obj is null
int i; // i is 0
double d; //d is 0

Related

C++/Java recursion variable initialize

I wonder why this C++ code is valid and doesn't cause any errors:
extern int B;
int A = B;
int B = A;
int main()
{
printf("%d\n", B);
system("pause");
return 0;
}
First, the variable A will be created in some memory address, then its value will be initialized from variable B, but then variable B goes back to initialize its value from variable A, and so on, ...
So, why is there no infinity loop or any error here?
The program still runs ok, and the value of B is 0
This is valid for Java as well:
class A {
static final int AA = B.BB;
}
class B {
static final int BB = A.AA;
}
Any one can explain these questions for me, thanks!
Since I´m not familiar with c++ I can only explain it to you with the java example.
I think this might explain the issue:
class A {
static final int AA = B.BB;
}
class B {
static final int BB = A.AA;
}
A.AA gets initialized with value 0
A.AA looks for B.BB
B.BB gets initialized with value 0
B.BB looks for A.AA
At this time A.AA already has the value zero (default value of int), so B.BB becomes 0.
A.AA becomes 0
I am answering this for C++. Although the story might not be all that different for Java
It is not an infinite loop because everything is resolved at compile time, and here is how:
The compiler sees that B is declared as extern
The linker knows that A has to be set to the value of whatever B is supposed to be when it is declared, so setting the value of A is delayed until much later
B is finally declared but since it is not assigned a value, it gets a default value of 0.
The linker finally resolves the value of A and can now set it to 0 as well.
Compiler compiles your program and the output is 0
See this answer for more details

try catch java -- java complaining that variable may not be initialized [duplicate]

When I try to compile this:
public static Rand searchCount (int[] x)
{
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
...
}
I get these errors:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
2 errors
It seems to me that I initialized them at the top of the method. What's going wrong?
You declared them, but you didn't initialize them. Initializing them is setting them equal to a value:
int a; // This is a declaration
a = 0; // This is an initialization
int b = 1; // This is a declaration and initialization
You get the error because you haven't initialized the variables, but you increment them (e.g., a++) in the for loop.
Java primitives have default values but as one user commented below
Their default value is zero when declared as class members. Local variables don't have default values
Local variables do not get default values. Their initial values are undefined with out assigning values by some means. Before you can use local variables they must be initialized.
There is a big difference when you declare a variable at class level (as a member ie. as a field) and at method level.
If you declare a field at class level they get default values according to their type. If you declare a variable at method level or as a block (means anycode inside {}) do not get any values and remain undefined until somehow they get some starting values ie some values assigned to them.
If they were declared as fields of the class then they would be really initialized with 0.
You're a bit confused because if you write:
class Clazz {
int a;
int b;
Clazz () {
super ();
b = 0;
}
public void printA () {
sout (a + b);
}
public static void main (String[] args) {
new Clazz ().printA ();
}
}
Then this code will print "0". It's because a special constructor will be called when you create new instance of Clazz. At first super () will be called, then field a will be initialized implicitly, and then line b = 0 will be executed.
You declared them, but not initialized.
int a; // declaration, unknown value
a = 0; // initialization
int a = 0; // declaration with initialization
You declared them, but you didn't initialize them with a value. Add something like this:
int a = 0;
You declared them but did not provide them with an intial value - thus, they're unintialized. Try something like:
public static Rand searchCount (int[] x)
{
int a = 0 ;
int b = 0 ;
and the warnings should go away.
Since no other answer has cited the Java language standard, I have decided to write an answer of my own:
In Java, local variables are not, by default, initialized with a certain value (unlike, for example, the field of classes). From the language specification one (§4.12.5) can read the following:
A local variable (§14.4, §14.14) must be explicitly given a value
before it is used, by either initialization (§14.4) or assignment
(§15.26), in a way that can be verified using the rules for definite
assignment (§16 (Definite Assignment)).
Therefore, since the variables a and b are not initialized :
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
the operations a++; and b++; could not produce any meaningful results, anyway. So it is logical for the compiler to notify you about it:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
However, one needs to understand that the fact that a++; and b++; could not produce any meaningful results has nothing to do with the reason why the compiler displays an error. But rather because it is explicitly set on the Java language specification that
A local variable (§14.4, §14.14) must be explicitly given a value (...)
To showcase the aforementioned point, let us change a bit your code to:
public static Rand searchCount (int[] x)
{
if(x == null || x.length == 0)
return null;
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if(l == 0)
a = l;
if(l == 1)
b = l;
}
...
}
So even though the code above can be formally proven to be valid (i.e., the variables a and b will be always assigned with the value 0 and 1, respectively) it is not the compiler job to try to analyze your application's logic, and neither does the rules of local variable initialization rely on that. The compiler checks if the variables a and b are initialized according to the local variable initialization rules, and reacts accordingly (e.g., displaying a compilation error).
You declared them at the start of the method, but you never initialized them. Initializing would be setting them equal to a value, such as:
int a = 0;
int b = 0;
Imagine what happens if x[l] is neither 0 nor 1 in the loop. In that case a and b will never be assigned to and have an undefined value.
You must initialize them both with some value, for example 0.
It's a good practice to initialize the local variables inside the method block before using it. Here is a mistake that a beginner may commit.
public static void main(String[] args){
int a;
int[] arr = {1,2,3,4,5};
for(int i=0; i<arr.length; i++){
a = arr[i];
}
System.out.println(a);
}
You may expect the console will show '5' but instead the compiler will throw 'variable a might not be initialized' error. Though one may think variable a is 'initialized' inside the for loop, the compiler does not think in that way. What if arr.length is 0? The for loop will not be run at all. Hence, the compiler will give variable a might not have been initialized to point out the potential danger and require you to initialize the variable.
To prevent this kind of error, just initialize the variable when you declare it.
int a = 0;
You haven't initialised a and b, only declared them. There is a subtle difference.
int a = 0;
int b = 0;
At least this is for C++, I presume Java is the same concept.
Set variable "a" to some value like this,
a=0;
Declaring and initialzing are both different.
Good Luck

Why this program does not give ambiguity error

I have a java program where a paramaterized constructor is used with the parameters names same as that of instance variables.
In such case we need to use this keyword. But when I do not use this keyword it does not gives any error instead it initializes instance variables with default values.
class Demo{
int a;
Demo(int a)
{
a = a;
}
public static void main(String args[])
{
Demo d = new Demo(5);
}
}
But when this program is executed the value of a becomes 0. How?
There's no ambiguity - in a = a;, both a's unambiguously refer to the parameter, because that is the "innermost" variable called a.
Because it is perfectly valid to assign the same value to same variable. So a = a is perfectly valid code.
But what you want to achieve is to assign value of a (method variable) to this.a (instance variable). So you need to use this keyword to refer to instance variable.
Demo(int a) {
this.a = a;
}
If you do not want to use this keyword then you need to rename method variable like
Demo(int b) {
a = b; // a will refer to instance variable in this case.
}
my question was how a's value become zero.
Refer : Primitive Data Types
Primitive datatype variable are initialized with default value. And for int 0 is default value.
You overwrite the local variable a in your code instead assigning it's value to the class variable. And the class variable is initialised with zero.
Do
Demo(int a) {
this.a = a;
}

Preparation stage and initialization stage of java class loader

I am not able to understand the difference between following lines ( http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.2 )
A) Preparation involves initializing static fields to the default values.
B) Initialization of a class consists of executing initializers for static fields (class variables) declared in the class.
Does it mean that 'a' will get assign the default value in "preparation" stage and 'b' will get assign the value in "Initialization" stage:
static int a;
static int b=2;
"Initializing to default values" means that the fields are set to the following values:
boolean: false
int, long, byte, short: 0
double, float: +0.0
char: '\u0000'
reference types: null
"Initializing by executing initializers" means that now the expressions that are assigned to those static fields are evaluated and assigned to them.
So, in the "preparation" stage, your a and b will be created and will receive the value 0. In the "initialization" stage, b will receive the value 2.
This is easy to verify using a method that has a side-effect. Instead of assigning simple "2" to b, we are calling a static method that returns the value 2, but it also prints information about the variables before doing so:
public class SimpleTest {
private static int a;
private static int b = printAAndBReturning2("initializer");
static {
printAAndBReturning2("static initializing block");
}
public static void main(String[] args) {
printAAndBReturning2("main");
}
public static int printAAndBReturning2(String where) {
System.out.printf("In %s a is %d and b is %d%n", where, SimpleTest.a, SimpleTest.b);
return 2;
}
}
The output is:
In initializer a is 0 and b is 0
In static initializing block a is 0 and b is 2
In main a is 0 and b is 2
This demonstration also serves to warn you about using methods that are ran during the initialization stage.
All fields of primitive types will be auto-initialized to default values.
For int is 0. So a == 0. You can check default values here.
It have the difference on non-primitive types (classes).
So
Font a; -> a == null (If you will try to use methods of a you will get a is not initialized.
Font b = new Font("Dialog", 16, Font.BOLD); -> b == ... (I think you understand).

initializing variables before using in java

I have been playing with this piece of code for sometime and it puzzles me why this method call seems to be returning a number although it was not initially set to 0
public class MainProg {
public static void main(String[] args) {
FixedCapacitySizeOfStrings s = new FixedCapacitySizeOfStrings(3);
System.out.println("(" + s.size() + " left on stack)");
}
}
This is the API code
public class FixedCapacitySizeOfStrings {
private String[] a;
private int N;
public FixedCapacitySizeOfStrings(int cap) {
a = new String[cap];
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N; //why is this line doing the right thing?? N was never initialized to 0
}
public void push(String item) {
a[N++] = item;
}
public String pop() {
return a[--N];
}
}
Primitive instance variables are by default initialized to 0. This includes int, long, double, float, short, byte and char. (And all non-primitive instance variables are initialized to null)
Note that it's only about instance variables (fields) - local variables are not initialized.
Instance variables are initialized to default value by the compiler,if you don't provide any initialization
These are the default values for different types of instance variables.
data type Default value
boolean false
char \u0000
int,short,byte / long 0 / 0L
float /double 0.0f / 0.0d
any reference type null
For more details on default initialization.
When you are inside of methods, variables must be initialized explicitly. Outside of methods 0 is implicitly the default value integers are initialized to.
So, even though your integer N is not being assigned within FixedCapacitySizeOfStrings its value is implicitly zero as it's declared as an instance variable (class variable.)
However, your test case complains because the integer s wasn't explicitly set to any value, and is being declared within a method.
FixedCapacitySizeOfStrings s = new FixedCapacitySizeOfStrings(3);
it will call the constructor, but before constructor it is called the initialisation code part, which is now empty and private int N; takes the 0 value. Than System.out.println("(" + s.size() + " left on stack)"); will return the 0 value.
it gives s.size()=0 because N is Instance variable and as you know it has default value if you want to correct value then write as
public int size() {
return N=a.length;
}
above give the correct result...

Categories