Every type in Java has a primitive value when declared. The article Primitive Data Types contains a description for primitive data types. Knowing this, why does Eclipse show an error telling me the variable may not have been initialized?
If I have, for example,
int x;
x++;
From the reference:
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
From the Java Language Specification, Java SE 8 Edition, 4.12.5 Initial Values of Variables:
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)).
Local variables don't get initialized.
This is a local variable:
void aaa() {
int x;
}
This is an instance variable. These do get initialized automatically:
class X {
int x;
}
Data 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
From the Primitive Data Types reference provided by you:
"Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error".
What you see is not an error, but your Eclipse preference. You can change it to ignore uninitialized variables in Eclipse preference.
Related
Does it have a value?
I am trying to understand what is the state of a declared but not-initialized variable/object in Java.
I cannot actually test it, because I keep getting the "Not Initialized" compile-error and I cannot seem to be able to suppress it.
Though for example, I would guess that if the variable would be an integer it could be equal to 0.
But what if the variable would be a String, would be it be equal to null or the isEmpty() would return true?
Is the value the same for all non-initialized variables? or every declaration (meaning, int, string, double etc) has a different value when not explicitly initialized?
UPDATE
So as I see now, it makes a big difference if the variable is declared locally or in the Class, though I seem to be unable to understand why when declaring as static in the class it gives no error, but when declaring in the main it produces the "Not Initialized" error.
How exactly a JVM does this is entirely up to the JVM and shouldn't matter for a programmer, since the compiler ensures that you do not read uninitialized local variables.
Fields however are different. They need not be assigned before reading them (unless they are final) and the value of a field that has not been assigned is null for reference types or the 0 value of the appropriate primitive type, if the field has a primitive type.
Using s.isEmpty() for a field String s; that has not been assigned results in a NullPointerException.
So as I see now, it makes a big difference if the variable is declared locally or in the Class, though I seem to be unable to understand why when declaring in the class it gives no error, but when declaring in the main it produces the "Not Initialized" error.
In general it's undesirable to work with values that do not have a value. For this reason the language designers had 2 choices:
a) define a default value for variables not yet initialized
b) prevent the programmers from accessing the variable before writing to them.
b) is hard to achieve for fields and therefore option a) was chosen for fields. (There could be multiple methods reading/writing that could be valid or invalid depending on the order of calls, which could only be determined at runtime).
For local variables option b) is viable, since all possible paths of the execution of the method can be checked for assignment statements. This option was chosen during the language design for local variables, since it can help to find many easy mistakes.
Fabian already provided a very clear answer, I just try to add the specification from the official documentation for reference.
Fields in Class
It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style.
If not specified the default value, it only be treated as a bad style, while it's not the same case in local variables.
Local Variables
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
The default value will be based on the type of the data and place where you are using initialized variable . Please refer below for Primitive default.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
I have scoured the Internet and have not found satisfying answers to my question. In a localized instance, if I have the code:
public static void main (String args[])
{
int x;
System.out.println(x);
}
...it will not compile, because the Java compiler will warn me that x should be initialized. I understand that.
My question is, will Java actually set aside 4 bytes of memory for the integer x? And if so, does it wipe out that block of memory? Does it define it as NULL (I don't think so because NULL and an int are incompatible types)? Or does the memory address of int x still retain the value last stored in memory, or does x just simply have "no value?"
I know that the above works in C, and that in C, it would just print out whatever is in that memory block. I want to know how Java handles this.
===EDIT===
Okay, okay. For some reason, my basic knowledge of programming had entirely exited my mind, as when a program does not compile, the question of memory allocation is irrelevant, as pointed out by both of the members who posted the answers. (Cue facepalm)
So what if I had the code:
public static void main (String args[])
{
int x;
}
How is the integer x resolved in memory then?
It's not a warning; it's a compiler error. That code won't compile, so no bytecode is generated. The question of whether memory is set aside is irrelevant, because there is no program to run.
However, if the x variable is not local, then Java will assign a default value of 0.
Section 4.12.5 of the JLS states:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):
For type byte, the default value is zero, that is, the value of (byte)0.
For type short, the default value is zero, that is, the value of (short)0.
For type int, the default value is zero, that is, 0.
For type long, the default value is zero, that is, 0L.
For type float, the default value is positive zero, that is, 0.0f.
For type double, the default value is positive zero, that is, 0.0d.
For type char, the default value is the null character, that is, '\u0000'.
For type boolean, the default value is false.
For all reference types (§4.3), the default value is null.
Each method parameter (§8.4.1) is initialized to the corresponding argument value provided by the invoker of the method (§15.12).
Each constructor parameter (§8.8.1) is initialized to the corresponding argument value provided by a class instance creation expression (§15.9) or explicit constructor invocation (§8.8.7).
An exception parameter (§14.20) is initialized to the thrown object representing the exception (§11.3, §14.18).
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)).
Given that your questions are:
[W]ill Java actually set aside 4 bytes of memory for the integer x?
And if so, does it wipe out that block of memory?
The answer you seek is in JLS 4.12.3.8:
A local variable declaration statement may contain an expression which initializes the variable. The local variable with an initializing expression is not initialized, however, until the local variable declaration statement that declares it is executed. (The rules of definite assignment (§16 (Definite Assignment)) prevent the value of a local variable from being used before it has been initialized or otherwise assigned a value.) The local variable effectively ceases to exist when the execution of the block or for statement is complete.
So the answers are:
Maybe. The value will be stored somewhere.
Yes. No uninitialized values are allowed by the JLS.
Nothing happens to the local variable until it is assigned. It is impossible to use the value until it has been assigned, however, so you can never use an uninitialized value. At the point of initialization, some sort of storage location must be used (obviously). However, nothing about the JLS requires the JVM to allocate memory.
Whether memory is allocated would be determined at runtime based on the execution context, whether the value needed to be pushed onto a stack frame to make a method call, whether an unused CPU register was available, etc. A naive JVM implementation might just always allocate memory, but that would be slow, and as such I would expect most real-world JVMs to try something more optimized.
I have one question: in java we declare int,long,double etc.,(primitive data)
or non primitive (object data), not initialized with default values, but at run
time it will take default values. Now my question is which one assigns
default values: java compiler or Java Virtual Machine (JVM)?
For Example:
int x;
System.out.println(x) //Result is 0;
There are three different types of declared variables in Java. They are instance, class and local variables.
Instance Variables
Instance variables are the non-static fields of your class, often referred to simply as fields.
Primitive numeric fields initialize to 0. This includes byte, short, int, long, float and double.
booleans initialize to false .
chars initialize to the null character \u0000.
Reference types initialize to null.
Class Variables
A class variable is a field within a class declared as static, often referred to as a static variable or static field. It is also same initialize as instance variable.
Local Variables
A local variable is a variable defined within a method, which includes any method
parameters.
Local variables must be initialized before use. They do not have a default value.
Initialization process is done by JVM when method is create.
The default values for fields are assigned by the JVM at runtime. From JLS 15.9.4 (emphasis mine):
The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value.
Of course, given that this behavior is standardized in the JLS, a compiler could conceivably take advantage of that to perform certain optimizations based on the assumption that uninitialized fields start with their default value.
Fields are initialized to the equivalent of 0 in whatever type they are (null for reference types). This article gives a nice list:
Data Type: Default Value:
boolean false
char \u0000
int,short,byte / long 0 / 0L
float / double 0.0f / 0.0d
any reference type null
Local variables are not given an initial value, and it is a compiler error to use them if they are not assigned a value through all possible code paths prior to use.
Note that array elements are automatically initialized to default values as well when a new array is created (e.g. each element of new int[100] will be initialized to 0). This applies to both field and local array variables.
To what value is a variable of the String type automatically initialized?
null
Unless it's inside a method (local variable), in which case it's not declared to anything.
Here's a summary of the answers posted by Martin v. Löwis and silky.
We can say the following about the initialization of a String object:
If the String is a local variable, it will not be initialized.
If the String is a class variable, instance variable, or an array component, then it will be initialized to null.
The reasoning is as follows:
As a variable with the type of String is a reference type, according to The Java Language Specification, Third Edition, Section 4.12.5: Initial Values of Variables says the following:
Every variable in a program must have
a value before its value is used
It goes on to say the following about the initialization of reference types:
Each class variable, instance variable, or array component is
initialized with a default value when
it is created (§15.9, §15.10):
[removed information on irrelevant information]
For all reference types (§4.3), the default value is null.
And finally, the follow about local variables:
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 by the
compiler using the rules for definite
assignment (§16).
If the variable is a class variable, instance variable, or array component, it is initialized to null (since the default value for a reference type is null)
If the variable is a local variable, then it must be given a value explicitly (i.e. it has no default value in this case).
A variable of type String is a reference variable. As an instance variable, it gets initialized to null, see the specification for the discussion of other cases.
It's null unless it's local, in which case it is technically uninitialized, but in fact you can't use it, for that reason, so the language is still type-safe. You can't deref a garbage pointer.
null
String str=null means that the str is a object of String class which is not pointing to anything...but when we talk abt memory allocation,memory will be allocated to str as soon as it comes into existence....u can check the amount of memory by using the profiling option in netbeans..
the string value should be NULL in default , no need to initialize it.
string class objects are NULL by default only if they are defined as class level atttributes, otherwise string objects don't have any default value they need to be explicity initialized.
If the variable of type String is within a method, it would not automatically initialise. Otherwise it would be initialised with null as a value.
Any variable that is declared within a class is automatically initialized.
Any variable that is declared within a method must be initialized otherwise it will generate an error.
Strings are initialized to null,ints to 0 and so on..
Check this page for more information...
public class Foo {
public static void main(String[] args) {
float f;
System.out.println(f);
}
}
The print statement causes the following compile-time error,
The local variable f may not have been initialized
If primitives in Java already have a default value (float = 0.0f), why am I required to define one?
Edit:
So, this works
public class Foo {
float f;
public static void main(String[] args) {
System.out.println(new Foo().f);
}
}
Thanks, everyone!
Because it's a local variable. This is why nothing is assigned to it :
Local variables are slightly different; the compiler never assigns a
default value to an uninitialized local variable. If you cannot
initialize your local variable where it is declared, make sure to
assign it a value before you attempt to use it. Accessing an
uninitialized local variable will result in a compile-time error.
Edit: Why does Java raise this compilation error ?
If we look at the IdentifierExpression.java class file, we will find this block :
...
if (field.isLocal()) {
LocalMember local = (LocalMember)field;
if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) {
env.error(where, "invalid.uplevel", id);
}
if (!vset.testVar(local.number)) {
env.error(where, "var.not.initialized", id);
vset.addVar(local.number);
}
local.readcount++;
}
...
As stated (if (!vset.testVar(local.number)) {), the JDK checks (with testVar) if the variable is assigned (Vset's source code where we can find testVar code). If not, it raises the error var.not.initialized from a properties file :
...
javac.err.var.not.initialized=\
Variable {0} may not have been initialized.
...
Source
In fact, the compiler does not assign a default value to your float f, because in this case it is a local variable -- and not a field:
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
Class fields (non-final ones anyway) are initialized to default values. Local variables are not.
It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler.
So a (non-final) field like f in
class C {
float f;
}
will be initialized to 0f but the local variable f in
void myMethod() {
float f;
}
will not be.
Local variables are treated differently from fields by the language. Local variables have a well-scoped lifetime, so any use before initialization is probably an error. Fields do not so the default initialization is often convenient.
Actually local variables are stored in stack.Hence there is a chance of taking any old value
present for the local variable.It is a big challenge for security reason..Hence java says you have to initialise a local varible before use.
Hi guys solution is simple.
the values that are stored on the heap memory are initialized by the compiler based datatype but local variables are stored on stack memory so we have to inialize it explictly.