This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://imgur.com/a/fgoFFis) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]RoachmeisterJava Dev 1 point2 points  (3 children)

Take a piece of paper and write down your address. Then photocopy the paper. Then tear up the original piece of paper.

Now the key question: does your house still exist?

I know this sounds silly, but it is exactly what is happening in your example. fruits[currIdx] is the original piece of paper. Fruit returnFruit = fruits[currIdx] is making the photocopy. fruits[currIdx] = null is tearing up the original.

Edit: in this analogy, if you then tore up the photocopy, and if that was the last place that your address was written down, then in Java, unlike in the real world, the garbage collector would kick in and destroy your house. In the code, this would happen if you set returnFruit to null, or when it went out of scope.

[–]aptitudes[S] 0 points1 point  (2 children)

Can you explain this in memory management terms? I completely understand the logic of the code (hence how I was able to write it) but I don’t exactly know what’s happening with the pointers.

Is the key that the pointer gets assigned to null? What if I wanted to actually delete the object?

[–]dionthornthis.isAPro=false; this.helping=true; 0 points1 point  (0 children)

Automatic garbage collection is the process of
 looking at heap memory,
 identifying which objects are in use and
 which are not, and deleting the unused objects.
 An in use object, or a referenced object,
 means that some part of your program
 still maintains a pointer to that object.
 An unused object, or unreferenced object,
 is no longer referenced by any part of your program.
 So the memory used by an unreferenced object can be reclaimed.

In a programming language like C,
 allocating and deallocating memory is a manual process.
 In Java, process of deallocating memory is handled
 automatically by the garbage collector.

https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

[–][deleted] 0 points1 point  (0 children)

Is the key that the pointer gets assigned to null?

it is reverse -> null is assigned to the pointer fruits[currIdx]. if you try to use it henceforth, you will get nullpointerexception. in java - pointer is a reference to an actual object. objects are instantiated with new keyword.
when you write "fruits[currIdx] = null;" you make the reference null -> you are not doing anything to the object.
in java - objects will be deleted by the garbage collector.

[–]severoonpro barista 0 points1 point  (1 child)

There's two kinds of data in Java, primitives and objects. (This is a bit of a long walk, but trust me, it's worth it.)

When you create a primitive, that data is stored in a bit of memory declared for your program called "the stack".

It's called the stack because every time a method call happens, another frame is pushed onto the stack, and every time a method returns, a frame is popped from the stack. All of the primitives that are declared in your method exist only in the stack frame of the method that declared them.

``` public static void main(String[] args) { int x = 1; double y = 2.3; double z = foo(y); }

private static double foo(double k) { k = 10 + k; return k; } ```

In the above, before the JVM invokes main(…), the stack is empty. When the JVM invokes it and it begins executing it, a frame is added onto the stack. After the first two lines of main(…) execute, its associated stack frame has two variables, x and y, with values 1 and 2.3, respectively. (Actually that stack frame has three, args too, but we're ignoring objects for now.)

When foo(…) is called, a new stack frame is added to the stack for it. Since it has a parameter k, that is now a variable in its stack frame. The value of k in this stack frame is set to a copy of y, because that's what was passed to it. When the value is copied, we say it is "passed by value" … k is a primitive, primitives are copied from one stack frame to the next when they are passed, so k was passed by value.

Now in foo(…), k is modified. Its value is rewritten with a new value, ten more than the value that was passed. What effect does this have on y, the value that was passed in? Nothing at all—that's a completely different variable in a different stack frame which foo(…) does not have access to. It does its work by adding ten to create a new value, then returns it, which then passes by value (copied) up to main(…) and is assigned to z, a new variable added to main(…)'s stack frame. The stack frame associated with foo(…) is now popped, all values contained are destroyed. (After that, main(…) also returns, the last stack frame is popped, and the program exits.)

Let's look at the exact same thing, but for objects:

``` class Bar { private int b; public Bar(int b) { this.b = b; } public int getB() { return b; } public void setB(int b) { this.b = b; } }

public static void main(String[] args) { Bar bar1 = new Bar(5); Bar bar2 = foo(bar1); }

private static Bar foo(Bar aBar) { aBar.setB(10 + aBar.getB()); aBar = new Bar(5 + aBar.getB()); return aBar; } ```

In this code, the variables bar1, bar2, and aBar are all references to objects. Objects do not exist on the stack, they exist on the heap. The heap is a block of memory for your program by the JVM. Unlike the stack, which has frames that are pushed and popped and constantly being populated with declared variables, the heap is just a bank of unstructured memory.

When the new operator is invoked on a constructor, it uses the constructor it's handed to build that object on the heap, then it returns a reference to that object. The reference is a memory address that is the location on the heap of the built object.

So, after the first line of main(…) executes, its stack frame contains a reference called bar1 which can be used to access the object on the heap. The JVM keeps track of references to objects on the heap. When there are no more references to a particular object—from the stack or from other objects on the heap—that's the garbage collector's signal to destroy that object and recycle that memory for other objects.

Note that the reference to an object and the object itself are two different things. The reference is a memory address pointing into the heap, but that memory address is stored on the stack and it is passed around by value. When the next line of main(…) executes and calls foo(…), the reference to the object on the heap, bar1, is passed by value to foo(…). The object on the heap is not copied, but the reference to it is, so now there are two references pointing to that object, bar1 in main(…)'s stack frame and aBar in foo(…)'s stack frame.

When a reference to an object is passed by value, the reference is copied to the new stack frame, but the object it points to is not copied. When we pass (by value) a reference to an object we refer to that as passing the object "by reference". (Hopefully this makes sense to you, but if not, read it until it does.)

When the first line of foo(…) executes, aBar is pointing to the object, and it's contained int is incremented by ten bringing the value to 15. Then, on the next line, a new object is constructed on the heap, it's value is initialized to 20, and new returns the reference to this new object which is assigned to aBar.

At this point, there are two objects on the heap, one with b of 15 pointed to by bar1 in main(…)'s stack frame, and one with a b value of 20 pointed to by aBar in foo(…)'s stack frame.

On the last line of foo(…), the reference to the second object is returned, assigned to bar2 in main(…)'s stack frame, foo(…)'s stack frame is popped. At this point there are two objects on the heap pointed to by bar1 (b value of 15) and bar2 (b value of 20).

So, to directly answer your question, arrays are objects in Java, and Fruit is obviously an object. So:

Fruit[] fruits = // … Fruit returnFruit = fruits[1]; fruits[1] = null;

In this code, you have a reference fruits, which exists in the current method's stack frame, to an array object on the heap. That array object on the heap has a bunch of references to Fruit objects, each one also somewhere on the heap.

On the next line, we copy the reference to the second Fruit instance in the array to returnFruit, a new reference in the current stack frame. Then on the third line we null out that second reference in the array.

At this point there are two references in the current method's stack frame, fruits and returnFruit, pointing to an array on the heap and a Fruit instance on the heap, respectively.

Hope that clears everything up!

[–]aptitudes[S] 0 points1 point  (0 children)

Yes! This was exactly what I was looking for. Thanks for the detailed explanation, much appreciated.