For a beginning course: no.
I have helped clarify behavior for fellow students who got lost by an instructor who explained things in terms of pointers. I have programmed in C, and most of my current programming is done in Rust; I understand pointers and what problems they are best suited to solve. But in Java, you don't have any access to pointers, so explaining pointers only serves to muddy the waters for a student trying to grep the way a computer thinks.
I take the position that a intro-level course should only cover programming, and the actual science of computer science should be postponed to at earliest 102. But my college also lacks a Software Engineering track, and I would argue most people pursuing a CS education actually want that instead of the science.
In any case, Java uses pass by reference. I know exactly what anyone who cares about terminology and grew up in C/++ is thinking as soon as I say that: Java is pass reference by value. But this is inconsistent with Java's own mental model.
Here's the mental model I have shared multiple times to great effect with students who failed to understand Java's Objects the first time:
A variable is a binding to a value. Thus, when you do Animal c = new Cat();
, c
is a binding to the constructed Cat
. This binding is transparent, and when you use it, you are talking directly to the bound object.
However, in order to facilitate resource sharing, when you pass this object as a parameter to a method, a new binding is created. This binding is to the same object, but is a new binding, so assignment to the binding does not effect the old one (the pass by value).
But because these two bindings are bound to the same object, there is only one object. This means that mutating this object by using its fields or methods will have the effect that the object the original binding is bound to also changes, because they are the same object.
Note that nothing about this mental model breaks on primitives (or the quasi-primitive String), since primitives can only be changed by reassigning. A slightly higher-level course, or even later in the course once students understand the shared resource concept, can mention that primitives aren't bindings but rather just their value.
Once binding misdirection gets multiple layers deep (Objects containing Objects containing etc), it can be useful to talk about and diagram name bindings as a pointer to a value, but that's as far as I go. Stack/Heap doesn't need to be discussed in a Java class: the GC and no stack allocated objects mean that just "somewhere in memory" is all that really needs to be mentioned on object storage until you're at an advanced level where cache coherency or GC overload matters.
Post Script:
I've called Java pass by reference here, which will (and has) riled up a bunch of people who want pass by reference to only mean what is expressed in C as function(&name)
, which Java is not doing. As such, it may be better to call it pass by resource sharing, pass by resource binding, or pass by binding. In C's definition, you are passing a copy of the reference by value (function(&*name)
). By my reading of Java, though, I argue that we are passing by the reference to the value, because the binding is not separate from the value. This is a terminology problem, and unfortunately, even in a field that relies on unambiguous interpretations, we do overload our terminology.