Difference between local variable initialize null and not initialize? - java

In Java, what is the difference and best way to do?
Integer x = null; // x later assign some value.
Integer y; // y later initialize and use it.

The answer depends on what type of variable are you referring.
For class variables, there's no difference, see the JLS - 4.12.5. Initial Values of Variables:
... Every variable in a program must have a value before its value is
used:
For all reference types (§4.3), the default value is null.
Meaning, there is no difference, the later is implicitly set to null.
If the variables are local, they must be assigned before you pass them to a method:
myMethod(x); //will compile :)
myMethod(y) //won't compile :(

Local variables must be assigned to something before they are used.
Integer x = null;
myFunction(x);
// myFunction is called with the argument null
Integer y;
myFunction(y);
// This will not compile because the variable has not been initialised
Class variables are always initialised to a default value (null for object types, something like zero for primitives) if you don't explicitly initialise them. Local variables are not implicitly initialised.

Its better to not set it to null, otherwise you can by accident use it and cause NPE. Compiler wont help you with compile error. Only set to null if you want to have logic like if ( x != null ) { /use it/ }

No difference at all. Both cases when ever you want to use it, local variable must be in initialized form(must have a value).
From Java doc
Similar to how an object stores its state in fields, a method will
often store its temporary state in local variables. The syntax for
declaring a local variable is similar to declaring a field (for
example, int count = 0;). There is no special keyword designating a
variable as local; that determination comes entirely from the location
in which the variable is declared — which is between the opening and
closing braces of a method. As such, local variables are only visible
to the methods in which they are declared; they are not accessible
from the rest of the class.

Internally there is no difference. Also it is a debatable topic.
Use the local variable only if it is really required. Local variables are mostly in the following scenarios (I may be missing few other).
As a shorthand or for Readability
Integer myObject = someObject.someFunction().someOtherFunction();
If we use the syntax like that in many places, code will become clumsy.
For accessibility
Object returnObject = null;
if(mycondition)
{
returnObject = value1;
}
else if(secondCondition)
{
returnObject = value2;
}
return returnObject;
The caller of the above code snippet will take decision based on the return value.
Honestly speaking i am not seeing other valid use case to declare a variable without initial value.
Conclusion (Best Practice):
Declare local variable only if required
Always create local variable with default value.

No differences at all expect for one thing, if you don't initialize it and later on you try to use this variable (without changing the reference) means an error at compilation time, but if you initialize it and you use it later on (without changing the reference) means a NullPointerException.
I show you with an example.
Without initializing
Integer y;
y.intValue(); // Compilation error
With initializing
Integer x = null;
x.intValue(); // You are able to compile it but NullPointerException

Related

Why don't we need to initialise instance variables [duplicate]

Consider the following code snippet in Java. It won't compile.
package temppkg;
final public class Main
{
private String x;
private int y;
private void show()
{
String z;
int a;
System.out.println(x.toString()); // Causes a NullPointerException but doesn't issue a compiler error.
System.out.println(y); // Works fine displaying its default value which is zero.
System.out.println(z.toString()); // Causes a compile-time error - variable z might not have been initialized.
System.out.println(a); // Causes a compile-time error - variable a might not have been initialized.
}
public static void main(String []args)
{
new Main().show();
}
}
Why do the class members (x and y) declared in the above code snippet not issue any compile-time error even though they are not explicitly initialized and only local variables are required to be initialized?
When in doubt, check the Java Language Specification (JLS).
In the introduction you'll find:
Chapter 16 describes the precise way in which the language ensures
that local variables are definitely set before use. While all other
variables are automatically initialized to a default value, the Java
programming language does not automatically initialize local variables
in order to avoid masking programming errors.
The first paragraph of chapter 16 states,
Each local variable and every blank final field must have a definitely
assigned value when any access of its value occurs....A Java compiler
must carry out a specific conservative flow analysis to make sure
that, for every access of a local variable or blank final field f, f
is definitely assigned before the access; otherwise a compile-time
error must occur.
The default values themselves are in section 4.12.5. The section opens with:
Each class variable, instance variable, or array component is
initialized with a default value when it is created.
...and then goes on to list all the default values.
The JLS is really not that hard to understand and I've found myself using it more and more to understand why Java does what it does...after all, it's the Java bible!
Why would they issue a compile warning?, as instance variables String will get a default value of null, and int will get a default value of 0.
The compiler has no way to know that x.toString(), will cause a runtime exception, because the value of null is not actually set till after runtime.
In general the compiler couldn't know for sure if a class member has or has not been initialized before. For example, you could have a setter method that sets the value for a class member, and another method which accesses that member. The compiler can't issue a warning when accessing that variable because it can't know whether the setter has been called before or not.
I agree that in this case (the member is private and there is no single method that writes the variable) it seems it could raise a warning from the compiler. Well, in fact you are still not sure that the variable has not been initialized since it could have been accessed via reflexion.
Thins are much easier with local variables, since they can't be accessed from outside the method, nor even via reflexion (afaik, please correct me if wrong), so the compiler can be a bit more helpful and warn us of uninitialized variables.
I hope this answer helps you :)
Class members could have been initialized elsewhere in your code, so the compiler can't see if they were initialized at compilation time.
Member variables are automatically initialized to their default values when you construct (instantiate) an object. That holds true even when you have manually initialized them, they will be initialized to default values first and then to the values you supplied.
This is a little little lengthy article but it explains it: Object initialization in Java
Whereas for the local variables (ones that are declared inside a method) are not initialized automatically, which means you have to do it manually, even if you want them to have their default values.
You can see what the default values are for variables with different data types here.
The default value for the reference type variables is null. That's why it's throwing NullPointerException on the following:
System.out.println(x.toString()); // Causes a NullPointerException but doesn't issue a compiler error.
In the following case, the compiler is smart enough to know that the variable is not initialized yet (because it's local and you haven't initialized it), that's why compilation issue:
System.out.println(z.toString()); // "Cuases a compile-time error - variable z might not have been initialized.

Accessing an uninitialised static field in Java

I'm indebted to this answer for the idea.
The following code compiles, but certainly shouldn't. It uses the value of x before it's been initialised. If you remove the StaticAssign. qualifier then it no longer compiles.
public class StaticAssign {
public static final int x;
static {
System.out.println(StaticAssign.x);
x = 5;
}
public static void main(String[] args) {}
}
On my machine, this consistently prints 0. If I change the type of x to String, it consistently prints null.
The question is: will it definitely print 0 or null, or might it access uninitialised memory and print out something else?
And even if this code gets through the compiler, why isn't it picked up by the JVM?
Is there a way to do nasty things based on this?
It actually has been initialized. Variables in the global scope are initialized automatically. Variables of Object type will be initialized to null primitive like int will be initialized to 0. A variable declared not in the global scope must be initialized ie. declared in a method. Another problem is declaring it as final this is telling the compiler it must be explicitly initialized. So by adding the x=5 you are bypassing the compiler error saying it must be explicitly initialized. When you access it before this line at run-time it is initialized to 0 like any other primitive int type variable in the global scope.
This is due to the way in which the classes are loaded.
First the class StaticAssign definition is loaded and the fields are initialized to default values:
StaticAssign.x = 0;
Then the initalization block is executed.
System.out.println(StaticAssign.x);
x = 5;
There is a reference to StaticAssign.x, the current class. As recursive initialization attempts are simply ignored, value of x is still 0.
This means that:
System.out.println(StaticAssign.x)
is valid because StaticAssign.x is a reference to field of an allready loaded class.
But if yo do:
System.out.println(x)
then x is a reference to a final uninitalized field.
On the other hand, you never will access uninitialised memory. When the class definition is loaded variables are initialized to default values, before the initalization block is executed.
EDIT:
There is a nice video "Elvis Lives Again" from Java Puzzlers that shows this much more better than I can explain

Default Values - Java Clarification

Why aren't default values assigned to the variables, that haven't been initialized within a Class with main function???
class Test {
public static void main(String[] args) {
int x;// x has no default value
String y;// y has no default value
System.out.println("x is " + );
System.out.println("y is " + );
}
}
Whereas the default values get assigned in case the variables remain uninitialized in a class without any main function.
class Student {
String name; // name has default value null
int age; // age has default value 0
boolean isScienceMajor; // isScienceMajor has default value false
char gender; // c has default value '\u0000'
int x;
String y;
}
Be aware that the code in the question represents different situations. In the first case, the variables are local and exist inside the main() method. In the second case you're declaring instance attributes, not local variables.
In Java, only the attributes are initialized automatically with default values. In all the methods, even in the main() method, you must explicitly provide an initialization value for the variables declared locally inside the method.
This is explained in the Java Language Specification, section §4.12.5:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10)
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)
To see several reasons why local variables are not initialized automatically, please take a look at this previous question.
The basic reason is that, in order to catch a common programmer error, the Java authors decided to ensure that every variable is assigned before it is used. However, it is not possible to enforce this for fields, so they had to spec default values for fields.
You do get an error if you use a field in a constructor before it is initialized, but there is no way for the compiler to prevent this:
class C {
int f;
C() {
init();
}
void init() {
System.out.println(f);
}
}
When the JVM is creating the new object instance, it has to allocate memory for the attributes because they are part of the class itself. The mere existence of a Java primitive int requires 4 bytes of memory to be allocated, whereas an Integer can be set to null since it's an object. That's why classes must have their attributes set to something upon being initialized.
Reading the value of a variable before it has been given a value is a common source of bugs. Forcing you to assign a value before using a variable makes programs safer: you'll know you'll get the value you expect and not some default value just because you didn't anticipate a certain program flow.
Unfortunately the liveness analysis that implementing this needs can only be done for local variables, and you can access instance fields before the program has initialized them with a value. To avoid unpredictable behavior the JVM initializes instance fields to default values.

Is initalization of string in java necessary...?

class TestMe{
public static void main (String args[]){
String s3;
System.out.print(s3);
}
}
why the compiler is giving a error,refernce object has a default value of null,why it is not the output...??
error: variable s3 might not have been initialized
It's an error because the JLS says so in §14.4.2. Execution of Local Variable Declarations:
If a declarator does not have an initialization expression, then every reference to the variable must be preceded by execution of an assignment to the variable, or a compile-time error occurs by the rules of §16.
local variables should be initialized before using them, local vars dont get default values in java, thus your string s3 doesn't get default value null as it is a local variable , thus the compiler error.
Fom JLS:
If a declarator does not have an initialization expression, then every
reference to the variable must be preceded by execution of an
assignment to the variable, or a compile-time error occurs by the
rules of §16.
The default value of null only applies to non-final fields of a class.
All other cases require initialisation before first use
Yes, it's necessary.
String s3;
s3 = "Something....";
System.out.print(s3); // prints "Something..."
Before you use a local variable, you have to initialize it.
what i know about local variables is:
Local variables are declared mostly to do some calculation.So it is the programmer's decision to give the value to the variable and it should not take default value. If programmer by mistake did not initialize a local variable, then it takes default value, then the output goes wrong. so local variables will ask programmer to initialize before he uses the variable to avoid making mistake.
The unique scenarios where defaut values are used are the cases where the concerned variables are object's fields or array's components even local. Indeed, arrays ALWAYS initializes their cells with their appropriate default values.
Thus, in your case, your variable doesn't come from a field ( since local to the method) and hasn't participated with an array initialization. So compiler logically complains ..

Why does java treat class scope and method scope differently when using uninitialized variables?

Java doesn't allow you to use an variable that may not have been initialized within a method scope. An uninitialized variable within a class scope may still be returned by a class method, and the value defaults to null.
Why the different treatment of the two different scopes?
public class TestClass {
Integer i;
Double d;
public TestClass() {
d = 1d;
}
public Double getD() {
return d;
}
public Integer getI() {
return i;
}
// public Integer getSomeInt() {
// Integer i;
// return i;
// }
public static void main(String[] args) {
TestClass myClass = new TestClass();
System.out.println(myClass.getI().getClass());
}
}
This results in a NullPointerException, but returning i within getSomeInt() is a compiler error because "the variable may not have been initialized".
The reason behind this are the limits of Java's static code analysis. The compiler is able to prove beyond doubt that you will not read a stack-allocated local var before initializing it. This is impossible to do for heap-allocated memory and therefore Java mandates that all heap-allocated storage be zeroed out before exposing a pointer to it.
The consequence of this rule is that everything heap-allocated has a default value of zero (false, null, whatever the binary zero amounts to for the type).
Because member variables have default value (if not initialized) and so the I has null and if you invoke method on null it will result on NullPointerException
and for local variables, they must be initialized before used otherwise it will turn into compile time error
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. [....]
It's quite simple really. Member variables get automatically initialized to their default values, while local variables does not.
When you do
public Integer getSomeInt() {
Integer i;
return i;
}
you hide this.i and in return i you refer to an (uninitialized) local variable.
So why are member variables initialized automatically while local variables are not?
Ultimately this is a question that only the designers of the language can answer, but if I had to guess I'd say it is due to the performance issue of having to zero out all memory being allocated. When it comes to objects, it would however be a pain to force the programmer to initialize all fields explicitly.
From the JLS (4.12.3 Kinds of Variables):
A class variable is created when its class or interface is prepared (§12.3.2) and
is initialized to a default value (§4.12.5).
[...]
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 (Chapter 16, Definite
Assignment) prevent the value of a local variable from being used before it has
been initialized or otherwise assigned a value.)
All fields are implicitly initialized in the constructor after the call to super but before anything else. Object references are set to null, primitive values are set to 0, false etc.
This implicit initialization isn't done in methods.

Categories