I have here a simple question related to Java.
Let's say you have an int array as instance variable:
int[] in = new int[5];
So, now by default it contains 5 zeros.
But what if you have the same array as local variable. Does it get initialized to zeros? That is not a homework, I am learning Java language.
Best regards
First thing to understand is that, local varibles are stored on stack which are not initialized explicitly with their default values. While instance variables are stored on Heap, and they are by default initialized with their default value.
Also, objects are also created on Heap, regardless of whether an instance reference variable is holding its reference, or a local reference variable.
Now, what happens is, when you declare your array reference like this as local variable, and initialize it with an array: -
int[] in = new int[5];
The array reference (in) is stored on stack, and a memory is allocated for array capable of holding 5 integer elements on heap (Remember, objects are created on Heap). Then, 5 contiguous memory location (size = 5), for storing integer value are allocated on Heap. And each index on array object holds a reference to those memory location in sequence. Then the array reference points to that array. So, since memory for 5 integer values are allocated on Heap, they are initialized to their default value.
And also, when you declare your array reference, and don't initialize it with any array object: -
int[] in;
The array reference is created on Stack (as it is a local variable), but it does not gets initialized to an array by default, and neither to null, as is the case with instance variables.
So, this is how allocation looks like when you use the first way of array declaration and initialization: -
"Your array reference"
"on stack"
| | "Array object on Heap"
+----+
| in |----------> ([0, 0, 0, 0, 0])
+----+
"Stack" "Heap"
It is the same thing if you do :
int[] in = new int[5] as instance variable or local variable. The array object in will contain zeros in both cases.
Difference would be if you would do something like :
Instance variable : int[] in; (it is initialized with null), and the in object will live in heap space.
Local variable : int[] in; (it has to be initialized by the user) will live in stack
For primitive type arrays it is initialized to their default values.
In the documentation it says :
a single-dimensional array is created of the specified length, and
each component of the array is initialized to its default value
For the integer type default value is 0.
Yes, when you initialise an array the contents will be set to the default value for that type, for int it would be 0 and for a reference type it would be null.
If you initialise an array and inspect the contents you can see this for yourself:
...
final int[] in = new int[5];
for (int i = 0; i < in.length; i++) {
System.out.println(in[i]);
}
...
This will print:
0
0
0
0
0
yes
public void method() {
int[] in = new int[5];
System.out.pritnln(in[0]); //output in 0
}
In this case, your Array is a local variable, all you need is to initialize your array. once you initialize you array, voila your array element**s get their **default values.
It does not really matter whether the declared array in an instance variable or a local variable it will get initialized to the default value.
Each class variable, instance variable, or array component is initialized with a default value when it is created.
As per JLS
An array initializer creates an array and provides initial values for all its components.
THe Array Doesn't Contain 5 zeroes when you instantiate it as a local variable.
Related
Is there any way to check if an array has already been set to a length in Java?
In my case, I have a recursive method, and in the first iteration of the method, I want the array to have the length of a variable n. However, after the first recursion of the method, I don't want the array to be reassigned a new size.
Additionally, I don't know what the size should be until the first iteration of the method.
Thanks!
The array variable would be null until you assign an instance to it. Once an instance is assigned, it will have a fixed length. Therefore, a simple null check would suffice.
The Array Reference Variable Would be NULL until you assign to it.
You cannot create an Array Object without a lenght; if you want that, maybe you should create a ArrayList, and you can add objects to it without care about the size.
If you just want to see the lenght of your Array; after CREATE, do this:
public static void main (String[] args){
String[] x = new String[2]; // you cannot create here without a lenght, you MUST set
System.out.println(x.length);
}
OUTPUT: 2
So I am having issues with a program i am trying to create. I cannot put in data into the array int[] serviceCode without the error
Exception in thread "main" java.lang.NullPointerException
at Job_18028094.<init>(Job_18028094.java:24)
at BMAS_Main_18028094.main(BMAS_Main_18028094.java:76)
Here is the relevant section of my code.
From my Main:
String[] tempRecords = fileScan.nextLine().split(",");
jobList[loopCount] = new Job_18028094(tempRecords);
From my class 'Job':
private int[] serviceCode;
public Job_18028094(String[] tempRecords) {
serviceCode[0] = Integer.parseInt(tempRecords[6]);
}
To clear things up, there is data held in tempRecords[6] as String (but is all numbers) and have been using Integer#parseInt prior to convert them. I researched what the error means and have turned up with it meaning that the variable is a 'null' value, but I am unsure as to how to change this or just over write it with the data in tempRecords.
Thank you in advance for any help :)
The NullPointerException is thrown , because the ServiceCode array is not initialized. Arrays are static objects and need to be initialized prior any use. Also, you should provide the size of this array before using it ! try to pass a "size" parameter to Job_18028094 constructor. This will solve the problem.
You have to initialize this array before use it.
private int[] serviceCode; // else serviceCode is null
You can use
private int[] serviceCode=new int[5];
If you are not sure about the length of the array. Use List
List<Integer> list=new ArrayList<>();
When you simply declare an array using the statement private int[] serviceCode;, you are telling to the compiler that a variable named serviceCode will hold an array of integers. At this point of time, compile is not informed about how many integers that the array will be holding. So the actual memory allocation to hold the integers will not happen by this time.
To start putting integers into an array, the corresponding memory allocation should have happened already. Compiler will take care of doing this memory allocation only when you initialize the array using the following statement.
int[] serviceCode = new int[5]
After the above initialization, memory allocation will be completed for the array to hold 5 integers and the array will be filled with the default values for the integers (which is '0'). Now you can start putting different values into the array.
In your case, since you have not initialized the array, memory allocation did not happen which caused the NullPointerException to be thrown when you tried accessing the array.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Are arrays passed by value or passed by reference in Java? [duplicate]
(7 answers)
Closed 9 years ago.
I have trouble with scope of variable.
public static void main(String[] args){
int[] test={1,2,3};
test(test);
System.out.println(test[0]+" "+test[1]+" "+test[2]);
}
static void test(int[] test){
test[0]=5;
}
I expected the output to 1 2 3, but the result was 5 2 3.
Why I changed the value in the array in the method, but the original array changed?
An array in Java is an object. When you create an array via new, it's created on the heap and a reference value (analogous to a pointer in C) is returned and assigned to your variable.
In C, this would be expressed as:
int *array = malloc(10 * sizeof(int));
When you pass that variable to a method, you're passing the reference value which is assigned (copied) to the local (stack) variable in the method. The contents of the array aren't being copied, only the reference value. Again, just like passing a pointer to a function in C.
So, when you modify the array in your method via that reference, you're modifying the single array object that exists on the heap.
You commented that you made a "copy" of the array via int[] temp=test ... again, this only makes a copy of the reference value (pointer) that points to the single array in memory. You now have three variables all holding the same reference to the same array (one in your main(), two in your method).
If you want to make a copy of the array's contents, Java provides a static method in the Arrays class:
int[] newArray = Arrays.copyOf(test, test.length);
This allocates a new array object on the heap (of the size specified by the second argument), copies the contents of your existing array to it, then returns the reference to that new array to you.
Definitions:
Reference = A variable that points to the location in memory where your array lives.
Value of a Reference = The actual memory address location itself
You passed the value of the reference of your array into your test() method. Since java is Pass By Value, it passes the value of the reference, not the value of your array (ie. a copy).
It may be easier to think of a reference as a pointer if you have a C background. So a value of a reference is essentially it's memory address (I'm fudging java rules here but it may be simplest to think of it this way)
So, in your example, you pass the value of the reference which points to your array, into your test() method, which then uses that reference value to lookup where your array is in memory, so it can access data in your array.
Since in your test() method you do not change your array's reference (where it points to, ie. test = new int[10];), then your test() method acts on the original data in the array (because it still points to your original array's location), leading to element 0 being set to a value of 5.
This question already has answers here:
What is the default initialization of an array in Java?
(8 answers)
Closed 9 years ago.
I have two-dimensional array
protected MyClass[][] myArray;
in constructor I have this
this.myArray= new MyClass[20][20];
Now, without inicialization (aka this.myArray[2][2] = new MyClass(par0, par1);)
the value of this.myArray[2][2] is "null".
Is this guaranteed? And where can I read more about this subject? (for primitive types like int or boolean too)
Thanks
Yes, it's guaranteed. Array values are initialized with null (for objects), 0 (for numeric primitives) and false (for boolean primitives), just like fields.
See http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.6-100:
Space is allocated for a new array of that length. If there is insufficient space to allocate the array, evaluation of the array initializer completes abruptly by throwing an OutOfMemoryError. Otherwise, a one-dimensional array is created of the specified length, and each component of the array is initialized to its default value (ยง4.12.5).
(emphasis mine)
Yes, it is guaranteed. Every type has a default initialization value:
numeric primitives = 0
boolean = false
all Objects = null
Yes. This behavior is guaranteed. The default value of an Object is null. Therefore the default values for an array of Objects is also null so every element in the array needs to be instantiated. See Default Values in Data Types.
This question already has answers here:
Are arrays passed by value or passed by reference in Java? [duplicate]
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed last month.
When I write like this:
public class test {
void mainx()
{
int fyeah[] = {2, 3, 4};
smth(fyeah);
System.out.println("x"+fyeah[0]);
}
void smth(int[] fyeah)
{
fyeah[0] = 22;
}
}
It prints x22;
When I write like this:
public class test {
void mainx()
{
int fyeah = 5;
smth(fyeah);
System.out.println("x"+fyeah);
}
void smth(int fyeah)
{
fyeah = 22;
}
}
It doesn't print x22, but prints x5.
Why, in the second version function, doesn't the value change? Does it change values only for array elements?
The fyeah variable in your first example contains a reference to an array (not an array), while the fyeah integer in your second example contains an integer.
Since Java passes everything by value the following will happen:
In the array case: A copy of the array reference will be sent, and the original array will be changed.
In the int case: A copy of the integer will be changed, and the original integer will not be changed.
It's because your int is a primitive and the method smth creates a local copy which is why it doesn't print the way you want. Objects are passed by value as well, but a value to the pointer in memory. So when it is changed, the pointer stays throughout both methods and you see the change. Read More Here
Ok. An int in java ( and really all languages that have strict data typing ) is a primitive data type. Its just a single variable of that data type. In java this means its passed by value to the method. So when you pass in the argument, a copy of the passed variable is created. Any operations that take place in the method act on that copy not the passed variable.
Actually in java EVERYTHING is passed by value but getting into the details of how that actually is true with what I am going to say next seems inadvisable.
With the array...its a collection of variables of the primitive data type int. So an entire copy of the array isn't actually made just a copy of the reference to the memory that stores the array. so yes the value of the int IN the array is changed from operations in the method.
In short methods don't change the external value of primitives (int,float,double,long,char) with the operations in the method, you have to return the resulting value of those operations to the caller if you wish to obtain it. Operations do change the value with most objects as well as with arrays of primitives. Hope that helps. Really unsure of how low level to get. Maybe someone else can clearly explain exactly why its by value. I "get" it but find it hard to help other people understand.
Think it in terms of memory: Lets analyse your first program -
In mainx , fyeah is an array of ints , so its a reference ( or a pointer if I may ). This reference points to a location in heap memory where the actual array of ints is stored. Lets say at address 100. Located contiguously from here are three ints ( lets say beginning at address 100 , 104 and 108 respectively are 2 ,3 and 4 ).
Now you call your method smth and pass the reference. Within the method , there is another reference ( of an int array type ) named fyeah. This fyeah is quite distinct from fyeah reference in the mainx method. Now , when you call smth and pass the fyeah from mainx , the fyeah within the smth method is initialized to point to the same location ( ie memory address 100 )
When you access the 0 element of fyeah and assign it a value of 22 , it reaches out to the memory location of 100 and writes this value 22 there. When you come back in your mainx method , the fyeah reference is still referring to memory address 100. But the value present at that location is now 22. So you get that value when you access the first element from fyeah in mainx.
Now , your second program. Your mainx method declares an int ( not an array , but a simple int ) and set it to 5. This fyeah variable is created on stack not on the heap. The value of 5 is stored on the stack. Now you call smth and pass this variable. Within the method smth , you again declare an int variable , fyeah by name ( as a formal method argument ). Again this is distinct from the fyeah of the mainx method and this fyeah is also created on stack.This variable will be initialized to a value of 5, copied over from the fyeah you passed to smth as argument. Note now that there are two distinct copies on fyeah variables , both on stack , and both a value of 5. Now you assign the fyeah in smth a value of 22. This will not affect the fyeah of the mainx method,so when you return to mainx and access fyeah , you see 5.
The int is a value type so 5 is passed directly into smth which can only modify the local copy. An array on the other hand is a reference type so the elements of that array can be modified.
Seeing it a bit less technically, I would say that
fyeah[0] = 22;
is changing the content of (the object pointed to by) fyeah, while
fyeah = 22;
is changing (the variable) fyeah itself.
Another example:
void smth(Person person) {
person.setAge(22);
}
is changing (the content of) the person while
void smth(Person person) {
person = otherPerson;
}
is changing the variable person - the original instance of Person is still unchanged (and, since Java is pass-by-value, the variable in the calling code is not changed by this method)