40
$\begingroup$

Many instructors teaching with Java started their education using earlier languages such as C or C++ in which pointers are essential. Pointers, however, are not a Java concept, though those same instructors may think of, for example, object references as pointers.

How important is it to teach pointers in a first Java course assuming the students don't have much of a prior programming background?

If you think it is important, say why, but also say how much of pointers do you think should be taught. Just as a metaphor/analogy? Or also including, say, pointer arithmetic?

If you think it is not important say why also.

Note that both Python and Ruby are similar to Java in lacking the "pointer" concept. References might be implemented as pointers or not, but the definition of reference is actually abstract in these languages.


Note that I take "pointer" to mean the actual machine address of some entity that might, in principle, be manipulated as an integer, whereas "reference" is a more abstract concept that implies that the entity may be accessed via the reference however implemented.

The Java language definition is careful not to discuss the implementation of references, explicitly disassociating them from the C-like notion of pointer.

$\endgroup$
18
  • 24
    $\begingroup$ Learning pointers is already quite hard ... but if you feel the need for an extra challenge, try learning what pointers are in a language which does not have pointers ... $\endgroup$ Jul 17, 2017 at 0:40
  • 19
    $\begingroup$ Whatever you do, don't talk about pointers in Java. Java does not have pointers. You can teach references, that's fine and necessary. Especially don't try to teach about memory addresses or pointer arithmetic because those are not things in Java. $\endgroup$
    – user253751
    Jul 17, 2017 at 1:04
  • 28
    $\begingroup$ If there are no pointers in Java, how do you get a NullPointerException? :) $\endgroup$
    – nova
    Jul 17, 2017 at 2:34
  • 10
    $\begingroup$ @nova - that's my go-to example for how the whole "no pointers" thing in Java is a poorly thought out whitewash. $\endgroup$
    – davidbak
    Jul 17, 2017 at 5:08
  • 6
    $\begingroup$ JLS Section 4.3.1 "The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object". Any assertion that Java doesn't have pointers is wrong. Maybe you want to just stick to the terminology of references but don't confuse the students with all the garbage about how Java passes objects by reference and primitives by value. Everything is passed by value. The value of the references is a pointer. $\endgroup$
    – JimmyJames
    Jul 18, 2017 at 15:16

20 Answers 20

31
$\begingroup$

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.

$\endgroup$
16
  • 4
    $\begingroup$ Really wonderful answer. "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." is exactly right. Come by the chat room to say hi, and welcome to Computer Science Educators! $\endgroup$
    – Ben I.
    Jul 16, 2017 at 16:33
  • 3
    $\begingroup$ I never did grok pointers and constantly had trouble with them when working in languages like C++ (I never could remember if I needed to * the variable or & and on which side that operator needed to go, because seriously, would it have killed someone to make that syntax consistent?). I hated pointers. Object references in languages like Java and C#? So easy to understand and use effectively. $\endgroup$ Jul 17, 2017 at 18:22
  • 4
    $\begingroup$ "Just confusing if you don't know pointers inside out." That's exactly my point. This is for an introductory class. The students do not know pointers inside out. $\endgroup$ Jul 17, 2017 at 18:30
  • 6
    $\begingroup$ Did you mean "grok" when you typed "grep"? That's a funny typo. :) $\endgroup$
    – Wildcard
    Jul 17, 2017 at 22:58
  • 3
    $\begingroup$ Pass by reference means that a called method can reassign the caller's variables to a distinct value. A good litmus test is whether you can write a function that swaps the caller's variables. Java doesn't enable this style of programming. Yes, it shoves the object on the heap, and the object can be mutated. But that isn't what "pass by reference" means; it means that full access to the caller's local variable is given. At this point, though, the matter is so widely confused that I'm not sure the terms have value anymore. $\endgroup$
    – jpmc26
    Jul 20, 2017 at 11:55
44
$\begingroup$

Learning about references is important, but I don't feel that learning about pointers is that important for beginning Java students. Certainly intermediate students will need to understand them.

When I started learning about pointers, I had a hard time grasping them at all until I learned assembly language. Once I learned assembly (for any processor), pointers made sense. It helped that I learned PDP-11 assembly at about the same time I learned C. Since C is essentially structured PDP-11 assembly language, I was easily able to see the relationship between the pointer structures and the compiled code.

Java hides the concept of a pointer sufficiently deeply that I would be hard pressed to explain it with java. I can explain java structures in terms of pointers, but have difficulty expressing it the other way around. For teaching pointers and pointer concepts, I would probably use C (yep - plain old C, without the ++) and the x86 assembly language as a starting point.

After that, it's easy to explain that the JVM is built in C, and java object references are implemented as pointers.

$\endgroup$
5
  • 8
    $\begingroup$ Yes. Build the ground floor before the next floor up gets built. It is very hard to put the ground floor in later. $\endgroup$
    – user737
    Jul 16, 2017 at 13:56
  • 2
    $\begingroup$ +1 I agree that pointers are sufficiently abstracted in reference based languages like Java, C#, and many others that they do not need to be covered in an introductory programming course. However, one potential pitfall many institutions fall into is the next instructor (for intermediate courses) tends to assume they have already been covered in earlier courses. $\endgroup$
    – Lee Hiles
    Jul 17, 2017 at 15:22
  • 3
    $\begingroup$ Irrespective of the importance, I can't say I shared your experience. Even having never programmed in assembly or seriously in C/C++ (just a couple college projects well after I had learned Java used pointers), I had no trouble grasping the idea that Java has your object's data in a separate block (over on the heap) and that the variable I'm using at the moment actually just corresponds to an address pointing to that block. Granted, that's a bit simplistic, but I didn't find the basic concept of pointers that hard, and even that limited understanding made Java's behavior more sensible. $\endgroup$
    – jpmc26
    Jul 18, 2017 at 0:36
  • 1
    $\begingroup$ @LeeHiles C# also has pointers, so that's not quite as good an example. Not quite as raw as C's, but then again C's aren't quite as raw as assembly's. E.g. there's no null pointer in assembly, that's a C construct; a pointer in assembly isn't necessarily a single integer; two pointers can point to the same memory despite having different values (and vice versa); I've got more where those came from :P In contrast, I've seen plenty of programs in C or Pascal that avoided pointers almost entirely (not counting "indexing a statically allocated array" as "using pointers"). $\endgroup$
    – Luaan
    Jul 18, 2017 at 13:13
  • 2
    $\begingroup$ @jpm26 java was invented about 20 years after I learned about pointers. I came through BASIC that was still close enough to its Fortran roots to be recognizable as such (no scope, so no distinction between references and values), into pascal and C. We have had different experiences for sure. $\endgroup$
    – pojo-guy
    Jul 22, 2017 at 17:54
16
$\begingroup$

No

Because of the way that you learn, you think of them as fundamental, to the way references work. They are not. References do not have to work this way. [I would still agree that pointers are fundamental to understanding memory in Von Neumann / Harvard architecture.]

Java uses references. You can think of these as being pointers, that must point to a valid object of the correct type or to the null object. But there are other ways to thing of references, e.g. like indexes, or like references (in a book or urls). You don't even need to know what is inside.

Other languages don't have references. E.g stack based languages.

Therefore they are not fundamental in any way.


My thought on types of references in Object Orientated Programming. See https://richarddelorenzi.wordpress.com/2009/08/10/types-of-reference/

A reference is free or fixed:

  • I fixed reference can not be reassigned. e.g. reference in (C++), const pointer (C++)
  • A free reference can be reassigned. e.g. pointer in (C++), reference in (C#, Java, python …)

A reference is:

  • not null-able: Can point to a valid object: e.g. Eiffel reference
  • null-able: Can point to a valid object or null. e.g. Java, C#, python, Traditional Eiffel, Eiffel null-able reference
  • radical: Can point anywhere. e.g. pointer, and even a reference in (C++)

A reference refers to something that is:

  • Constant
  • Mutable
$\endgroup$
7
  • 5
    $\begingroup$ @nocomprende while I agree with what you are saying, we must be interpreting the results wrong. For how do we explain young children programming in scratch without first learning how a transistor works? I think the foundation that we build on can be, how it works (how in this language it is implemented). Or it could be based on, what it does. It is a reference, so it is like a URL, or an index entry in a book. $\endgroup$ Jul 16, 2017 at 14:04
  • $\begingroup$ @alephzero (BenI. and richard and anyone else who wants to discuss) Feel free to continue this interesting conversation in this new room in chat. $\endgroup$
    – thesecretmaster
    Jul 16, 2017 at 22:32
  • 2
    $\begingroup$ @nocomprende Surely learning abstractions first then delving into into the detail behind them is how we learn almost everything? $\endgroup$ Jul 18, 2017 at 13:54
  • 1
    $\begingroup$ e.g. period table -> molecules and atoms -> quantum field theory. You certainly wouldn't want to do that in the reverse order, in large part because, as you say, it's better to start with concrete, accessible examples. And I'd suggest that learning about the workings of a computer is similar. Scratch exists because creating simple programs is accessible and concrete. Building understanding all the way up from transistors would be the opposite. $\endgroup$ Jul 18, 2017 at 16:40
  • 1
    $\begingroup$ @nocomprende I made a similar comment in the chat link above, but you shouldn't conflate what you teach somebody with which order you teach it. I wouldn't hire a software developer who knew about transistors but had no conception of writing code, either, but that's not a position anyone's promoting. $\endgroup$ Jul 18, 2017 at 17:39
13
$\begingroup$

What is important is to teach students the difference between Java objects, and Java variables. There are thousands of questions on Stack Overflow asked by students and by junior developers who do not understand the difference.

When we write Foobar f = new Foobar(...), it's much easier to say that f is a Foobar than it is to say that f holds a reference to a Foobar---I am guilty of taking that shortcut all the time---but nobody can get past the beginner stage until they learn that non-primitive Java variables only ever hold object references, and that the objects themselves only exist in a far-away place called "the heap."

$\endgroup$
2
11
$\begingroup$

A related (rhetorical) question:

Should C students be taught the [machine language] idea of reusing a pointer as a CPU instruction if the value happens to line up?

The speaker in a Functional Programming talk I recently saw discussed part of the history of programming languages, and the opinion seriously held by some at one time that assembly language was too far abstracted because it didn't allow you to reuse CPU instruction codes as pointers and vice-versa if the values lined up. :)

Also related (classic): The Story of Mel.

Then, the follow-up: How is that fundamentally different from teaching Java students pointer arithmetic?


Of course, this is a trick answer, because I do think both concepts (pointer arithmetic and reusing pointers as instructions) should be taught to Java students as ideas. As part of the history of the subject, and the layers of abstraction underneath the level they're working at.

But you shouldn't make them actually do any pointer arithmetic. It's totally sufficient that they understand that there is such a thing and have some idea about roughly how it was done. It's just a significance that they're not going to actually use in Java, so it's good background, but don't overdo it. It's not closely related to what you're teaching them to DO.

Your students need to have:

  1. An excellent mastery on the practical skills they need to code in Java, and
  2. A clear enough understanding of the theory and underlying concepts and background of what they are doing that they won't become obsolete after some new CS breakthrough or new language or new industry direction.

Does the concept of pointer arithmetic belong in a FIRST class on Java? That depends considerably on how long the course is.

I would say in a full semester course it would deserve perhaps a ten minute discussion at some point fairly well into the course, just for some comparative approach to Java's references and to emphasize that pointers are still used under the hood. And so that your students understand that there are other ways to do things than how Java does them.


(The balance between theoretical and practical knowledge I am advocating here is well conveyed in Mr. Hubbard's Study Technology, which I highly recommend for all educators and students.)

$\endgroup$
1
  • 2
    $\begingroup$ Oh yes, I remember that story of Mel. Is a cute story but code like that is fundamentally unmaintainable, which the story also shows. Real software can't work like that because (unethical or not) change requests come in and you can't just add a new feature to golf'ed code. $\endgroup$ Jul 18, 2017 at 13:12
9
$\begingroup$

As someone who learned to program with ruby, I think that the concept of how a reference to an object works under the hood is vital. Having the knowledge that "under the hood" my variables may be represented as pointers to values makes certain things much easier to understand. For example, in ruby:

a = Object.new
b = a.clone
c = a
c == b #=> false
c == a #=> true

Behavior like this could be seen as mind boggling: Why are 2 empty Objects the same, but the other 2 are not? But when given the conceptual knowledge that a pointer is a reference to a value this can be understood because a and c both point to the same Object in memory, while b points to a different object. Thus they have different Object IDs (a.object_id == b.object_id #=> false) and:

# Define a setter and getter for the test variable
a.instance_exec { def self.test; @test; end; def self.test=(new_val); @test=new_val; end }
a.test = "Foo"
c.test == "Foo" #=> true
b.test == "Foo" #=> NoMethodError

In summary, I think that it's very important to include the concept of what a pointer is in the class, but there's no need to go into the down and dirty details unless the students will actually have to work with pointers.

The basics of what a pointer is (an integer memory address) should still be mentioned, because that gives basis to the otherwise abstract concept of a "reference". Students tend to find it useful to actually understand what's going on in hardware in that case.

$\endgroup$
7
  • 9
    $\begingroup$ This doesn't require knowledge of pointers. It's rather easy to explain to students that you can have two different objects that are identical, but are just copies of each other. That way, Object.new creates a new, identical function reference. (Which, incidentally, is basically how Java does it) $\endgroup$ Jul 16, 2017 at 14:49
  • 1
    $\begingroup$ @NathanMerrill deep copy or shallow copy? I would say: teach a simpler language first. We can save the holy war inducing philosophical concepts until later. $\endgroup$
    – user737
    Jul 16, 2017 at 17:26
  • 1
    $\begingroup$ I wasn't saying that we are copying function references. Rather that they are "copies" (meaning that they look identical). That said, "duplicates" is likely a better word. $\endgroup$ Jul 16, 2017 at 21:54
  • 1
    $\begingroup$ There's nothing "under the hood" in your example. You merely are illustrating the difference between Ruby objects and Ruby variables. $\endgroup$ Jul 17, 2017 at 22:04
  • 1
    $\begingroup$ Re, "Why are 2 empty Objects the same, but the other 2 are not?" There's no "other 2" in your example: It only creates two objects. a, b, and c are not objects. They are variables. They refer to objects, and in particular, a and c refer to the same object, while b refers to a different object. $\endgroup$ Jul 17, 2017 at 22:06
8
$\begingroup$

No, you don't need to talk about pointers in an introductory Java class. You should talk about references, but even then you should keep it at a very high level.

The best tutorial on references I've seen is Cup Size -- a story about variables and its follow up Pass-by-Value Please. These talk about variables as cups that can hold different items, and references as remote controls that you can put in a cup. You can have two remote controls in two cups that control the same TV, and replacing one of the remote controls with another one that controls a different TV doesn't affect the first TV at all. This also clears up the misconception that Java is "pass-by-reference for objects" when in fact Java is always pass-by-value.

I think this kind of high-level language is what you should be using. You shouldn't get into the low-level details, and you shouldn't even use the word pointer at all.

$\endgroup$
1
  • 2
    $\begingroup$ I love those stories! I can imagine bringing various Starbucks cups into class for a physical demonstration.... welcome to Computer Science Educators. I hope we hear more from you in the future! $\endgroup$
    – Ben I.
    Jul 17, 2017 at 16:30
7
$\begingroup$

I think you're asking the wrong question. In my opinion the right questions are:

  1. Is it important to teach pointers at some point in the curriculum?
  2. If so, which courses in the curriculum are most suitable for teaching them? (Plural to cover cases where some of the courses are optional, or where students may not grasp the concept the first time and may need reinforcement later).
  3. Are there any courses which are taught earlier and which will suffer from students not understanding them?

I think it should be self-evident that pointers don't need to be taught in the first programming course: if it isn't, then consider that the first course may use e.g. Haskell, and it would be crazy to try teaching pointers using Haskell. (Of course, if the first programming course uses C then question 3 becomes relevant).

But a stronger statement can be made: it may be that the best course to teach them isn't a programming course at all. If pointers were mentioned at all in the university CS course I studied then it was either in Computer Architecture or Comparative Programming Languages (probably in the lecture on BCPL).

Question 1 is something that we can debate without additional context. But we can't answer questions 2 and 3 unless you supply considerably more detail about the curriculum. And since the question posed is really a subquestion of questions 2 and 3, I don't think we can give you a useful answer to the question as stated.

$\endgroup$
1
  • $\begingroup$ Yes, I was asking about the first course only. And agree with your comments. +1 $\endgroup$
    – Buffy
    Jul 17, 2017 at 14:21
6
$\begingroup$

Pointers as used in C and C++ are a fairly specific implementation of a general concept. The details of that particular implementation are mostly irrelevant--even to people using C and/or C++, many of the details are generally irrelevant.

The general concept is indirection (and dereferencing). Indirection arises in many forms; pointers are one version of it--but so are (for only one example) foreign keys in a SQL database.

The strength (and weakness) of pointers in C and C++ is that they're a relatively general implementation of indirection. On one hand, this means that when a student has learned them, most other (more restricted) forms of indirection are fairly easy and straightforward to deal with. On the other hand, it also means that they're a fairly daunting problem for many people approaching indirection for the first time. Pointers in C and C++ are also (for one example) a common place in which the pre- and post-increment and -decrement operators are used--so when students are supposed to be learning about indirection, it's easy for them to get side-tracked into truly ugly details about the degree to which C and C++ specify (and more to the point, mostly don't specify) sequencing of these operations.

Personally, I think I got somewhat lucky in my timing in learning about such things. The first language in which I was exposed to pointers was Pascal. It had (still has, for the relatively few who still use it) a relatively clean implementation of indirection. You can dynamically allocate an object, and what you get back is a pointer. You can then dereference that pointer to get to the object you allocated. You can do things like assigning and passing pointers as parameters--but that's pretty much it. You don't get into a lot of other details about things like pointer arithmetic that are fairly central to C, but basically irrelevant to the core concept of indirection.

Java, of course, is a poor choice of vehicles for teaching this concept (or much of anything else, but I digress). It attempts to hide the concept of indirection, which makes it more difficult to teach. At the same time, what it provides is (at best) an extremely leaky abstraction. A language that claims it doesn't use pointers, but does use NullPointerExceptions leads to confusion, not enlightenment.

Given that you're apparently already using Java, perhaps it wouldn't be too much of a stretch to provide your students with at least a little exposure to Clojure. This will let you do at least a little exploration of indirection without getting into a lot of ugly details about C and C++ that are difficult to avoid, but irrelevant to the underlying concept.

$\endgroup$
4
  • $\begingroup$ Hi Jerry! Welcome to Computer Science Educators! Thanks for this very interesting answer! I hope to see you around, doing more asking or answering! $\endgroup$
    – thesecretmaster
    Jul 16, 2017 at 20:51
  • 1
    $\begingroup$ IMO a null reference exception is pretty easy to understand "You tried to use an object that didn't exist." That is, you declared it but you didn't define it. Pointers let you do god awful things like int val = *somoeObj; val++; Object foo = &val No really. Why would you do that. Why would you EVER BE ALLOWED TO DO THAT. $\endgroup$ Jul 17, 2017 at 18:27
  • $\begingroup$ @Draco18s, I wonder if you saw my answer? :) I would enjoy listening to a conversation between you and Mel. $\endgroup$
    – Wildcard
    Jul 18, 2017 at 3:15
  • $\begingroup$ @Wildcard I have now, and I can respect that opinion. Not sure how much I agree (at least half?) $\endgroup$ Jul 18, 2017 at 13:04
4
$\begingroup$

Here is what it is important to know early.

  1. Primitive type variables store their value directly (I say: "Primitive types point directly at their values.")
  2. Object type variables store the location of their objects in memory. I say: "Object variables know where their object is in memory.
  3. Java is a strictly pass-by-value language in this sense: functions get a copy of the value stored by the variable passed them.
  4. If you pass a variable pointing at a mutable object to a function, and the function changes that object's state (e.g. remove an item from an ArrayList), the object itself is changed. Why? Because you passed that object's location in memory to the function and the callee used a mutator method on that object. BANG! Object state is changed.
  5. In reference to the last item, you can treat variables pointing to primitive types as if they were pointing at immutable objects, since a copy of the variable's value is made and the original cannot be changed.

Knowing these things early saves a lot of confusion.

$\endgroup$
4
$\begingroup$

Maybe you are thinking about memory management and pointer arithmetics. There is no need for that in the first course.

However I think that it is important to teach students that in Java object are created on heap and you have named pointers (which they call references) that you pass by value when you call a method (similarity with C language).

So Java does have pointers. What Java lacks, is pointer arithmetic. For example if you define an object like this: Integer pointsToAnInt = 5 that will create a pointer 'pointsToAnInt' to a location in memory that contains number 5.

If you say pointsToAnInt = null; and then call pointsToAnInt.intValue(); you will get NullPointerException because that pointer points to null.

From the Java language specification: Chapter 4. Types, Values, and Variables

An object is a class instance or an array. The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.

So for marketing reasons Java didn't mention pointers and they called them references but essentially you use pointers and you can get NullPointerException.

On the other hand C++ can pass values by references which Java cannot because Java is pass by value. So references should be something different but in Java a reference to an object is just a pointer to that object and you pass that pointer by value through stack while objects are created on heap and they are garbage collected when there are no more pointers that point to them.

Edit: By using sun.misc.Unsafe you can convert an int to an arbitrary address of an entity. In that case you can also have pointer arithmetic. In my personal experience telling people that Java does not have pointers did a great damage to understanding Java and introduced confusion among people to think that Java is pass-by-reference.

In C# you can pass by reference with ref keyword so you can make a swap function that you cannot make in Java static void SwapStrings(ref string s1, ref string s2). If you omit keyword ref then you get the same behavior like in Java and that is pass by value.

$\endgroup$
8
  • $\begingroup$ If you read my answer you'll see I disagree with that answer about Java and pass-by-value (for object types). It's not worth arguing though because it's just saying the same thing two different ways. $\endgroup$
    – CAD97
    Jul 17, 2017 at 4:49
  • $\begingroup$ Oh, and welcome to Computer Science Educators! (I'm almost as new, am I qualified to say that?) $\endgroup$
    – CAD97
    Jul 17, 2017 at 4:50
  • 1
    $\begingroup$ @CAD97 You certainly are :) I hope we see more of both of you. $\endgroup$
    – Ben I.
    Jul 17, 2017 at 4:53
  • $\begingroup$ Hi CAD97, thank you for your comment. I posted my answer to add additional things to your answer because I don't have enough reputation points to post a comments on other people's answers. Anyways you could copy from my answer a link to Java Language Specification where it says that references are pointers to objects. All the best. $\endgroup$ Jul 17, 2017 at 5:01
  • 1
    $\begingroup$ CAD97, in C# you can pass by reference with ref keyword so you can make a swap function that you cannot make in Java static void SwapStrings(ref string s1, ref string s2) . If you omit keyword ref then you get the same behavior like in Java and that is pass by value. If you think that it is pass by reference then how you call it when you use ref keyword in C#? $\endgroup$ Jul 17, 2017 at 14:15
3
$\begingroup$

As someone who is self-taught with Python, I'd say it depends on where your students are at. If they're beginning students - no, I don't think you need too. But as your students advance, it becomes a better idea. First, it's a good idea for programmers to understand multiple languages, including languages that use pointers. Second, the term is often thrown around on forums or in books - it's good to know the lingo. Finally, when I did learn the basics of what a pointer was, it was useful for understanding how memory worked - it's good to understand the basics of lower level actions the computer takes to make your program run.

$\endgroup$
3
$\begingroup$

No. Java and Smalltalk were designed as true object oriented languages. Bjarne Stroustrup who defined and wrote the C++ programming language also had the goal of object orientation but had to carry the baggage of the procedural and scripted C programming language due to the installed user base. If he had gotten rid of pointers and other ool polluters, it would have involved a much greater overhaul of the compilers.

The compilers are the main workload when designing a new programming language since you have to write a customized compiler for each hardware and OS platform, which is very non-trivial.

I would avoid teaching not just pointers but all OOL polluters for the following reasons:

Times have changed and your students may be beginners now, but eventually they will be writing code to perform:

writing classes for inheritable exception handling, remember for each feature of a program, you have to typically write 5 - 10 exception handling classes. Well designed software would handle errors so well that they would be invisible to the user. When things do go wrong, an analyst will have a much easier time with inheritable and extendable exception classes.

Object design for artificial intelligence

Both of the above require pure knowledge of OOL. Pointers would just confuse them.

You can teach pointers to a hacking class.

$\endgroup$
1
3
$\begingroup$

This is a tricky issue and where I think using a bit of formal semantics may help. Of course you don't want to introduce Greek letters and inference rules for undergrads but the concepts should be laid out clearly.

The most important thing I do early when presenting a programming language is to distinguish between syntax (how you write) and semantics (how things run. I later divide it into static semantics --typing-- and dynamic semantics). So here, as others have said, introducing pointers is not a good thing and goes against the spirit of Java (pointers don't exist). But you should present something namely what a value is in Java. The notion of value is fundamental. What is the result when a particular piece of code (syntax) is evaluated.

In Java constants of primitive types are their own values, but Objects on the other hand evaluate to a unique identity (whether you want to say that this identity is the memory address depends on your students and their backgrounds). It's a bit abstract but it allows you to explain several behaviours of the language. For instance, if you pass an object as argument to a method and perform mutation, the object is mutated (although the language is "call by value", since the value of the object is its unique ID, the modification occur on this particular object, not a copy). Conversely, even if you create two instances of the same class with the same internal content (say Point p1 = new Point(0,0) and Point p2 = new Point(0,0)) both objects will compare unequal (with ==). Which then allows you to also introduce why you should compare String object with .equals and so on.

The fact that some languages allow to manipulate this unique identity (pointers, pointer arithmetic etc…) is orthogonal, and imho should not be used to justify the behaviour of Java. It can certainly help as an analogy if the students have prior background in C/C++ but introducing a foreign low-level concept is not way to go.

In summary, you should not introduce pointers but this is not an excuse to not to explain precisely what is going on (call by value semantics with value being unique identities for Objects).

$\endgroup$
2
$\begingroup$

Some people use the term "pointers" to describe Java references. References definitely do need to be described (though they should be called references rather than pointers). Fields, variables, and parameters of class type are often treated as though they hold instances, but they never actually do.

Reference-type variables can hold four different kinds of things:

  1. A reference to an object that will never change (often an immutable type like String), which is used to encapsulate the contents thereof.

  2. A unshared reference to an object, which could be mutable, used to encapsulate the contents thereof.

  3. A reference to an object that is "owned" by the entity holding the reference, but which may also identified by references held by other entitites that don't own it.

  4. A reference to an object that is "owned" by some other entity.

The Java language makes no distinction among these different categories of references, but one cannot reasonably expect to write code which is efficient and correct without knowing which category every reference belongs to. In the first two situations, code may treat a reference-type variable as though it holds the object identified thereby, but a programmer must know which of those two situations applies.

If field arr of some object holds a reference to an int[] containing {1,2,3}, and one wants arr to hold a reference to an array holding {1,2,4}, there are two ways of accomplishing that: change the third item of the int[], or create a new int[] holding {1,2,4} and store a reference to that in arr. Either approach may be correct, but if one doesn't know into which category arr belongs, one won't know which approach to use.

$\endgroup$
4
  • $\begingroup$ Putting words in quotes does not make clear the idiosyncratic meaning you intend but do not give. $\endgroup$
    – philipxy
    Nov 12, 2020 at 6:42
  • $\begingroup$ @philipxy: Are you talking about "owned"? The idea there is that in cases where references to a mutable object are shared, only one entity--the "owner"--will hold a reference that it would be expected to use in any way it sees fit, and all other entities that hold references would be expected to use them only to perform actions on behalf of that "owner". For example, if a GUI object that displays a list subscribes to an update event from an "observable list" object, that list object will need to hold a reference to a delegate which will in turn hold a reference to the GUI object. $\endgroup$
    – supercat
    Nov 12, 2020 at 15:45
  • $\begingroup$ The sole purpose of the delegate will be to invoke a method which was designated by the GUI object, on the GUI object, when it's necessary to notify it that the contents of the list have changed. Calling that method will likely modify the GUI object, but the GUI object wouldn't be "owned" by the observable list object but instead by the GUI window/form object in which it appears. $\endgroup$
    – supercat
    Nov 12, 2020 at 15:48
  • $\begingroup$ @philipxy: I didn't want to fall into the rabbit hole of trying to describe why entities might hold references to objects whose state they don't regard as their own, perhaps you might offer some idea how to convey that concept in more detail than just the term "own", but without getting bogged down? $\endgroup$
    – supercat
    Nov 12, 2020 at 16:29
1
$\begingroup$

Learning pointers is not vital for learning Java, although references become very important once arrays or class instances are introduced given the importance between a reference type or a native type makes when cloning instances (shallow vs. deep copying), passing parameters into methods, or discussions regarding instance hash writing (needed for some of the ordered containers).

$\endgroup$
1
1
$\begingroup$

I think, no and yes. Students should know that somewhere in Memory lies an object with the values involved. They don't need to know that an internal representation is likely a memory address. Concepts that are alien to Java such as offsets and such can be ignored.

$\endgroup$
2
  • $\begingroup$ This is what I say to my students, "somewhere in memory this object exists, and this 'reference' points to it, like a piece of paper with a street address written on it points to my house. I can duplicate the piece of paper and give it to someone else, but I still only have one house. If I destroy the copy of the paper, the house doesn't go away. But if I destroy my only copy, I won't know how to get there anymore." This doesn't have to be so complicated. If a reference is not effectively a location in memory (like a street address is a location in space) then what the heck actually is it? $\endgroup$
    – user737
    Jul 18, 2017 at 16:31
  • 1
    $\begingroup$ Also, welcome to Computer Science Educators! $\endgroup$
    – Ben I.
    Jul 18, 2017 at 17:23
1
$\begingroup$

You need to teach about the references, regardless how you call them.

Even if you do not see the reference as a pointer, you absolutely need to explain what the reference is, as otherwise no student will understand the things going on behind

a.x = 1;
b = a;
b.x = 2;
a.x == // WTF?

or, with arrays:

a[0] = 1;
b = a;
b[0] = 2;
a[0] == // WTF?

And it is really not the best idea just to keep secret from the students how the values would change. These cases are frequent in Java code, they are far from the corner cases nobody needs to care about.

And the reference is easiest to explain in terms "it is the address in computer memory". Maybe a reference is also something deeply fundamentally else but I still need to see the easier understandable explanation and, well ... it just is, unless we start talking abut the physical, virtual address, address translation, handles that need to be resolved into addresses and other advanced concepts.

$\endgroup$
1
  • $\begingroup$ Welcome to Computer Science Educators! Wow! This is a wonderful answer. I hope we'll be hearing more from you. $\endgroup$
    – ItamarG3
    Jul 20, 2017 at 10:49
1
$\begingroup$

The following sentence from JLS Section 4.3.1

"The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object".

is sometimes exhibited as an "proof" that Java actually has pointers.

Putting it in context:

  • Language specification documents are not the kind of material beginners are expected to learn programming from ;
  • at the time (90's), "serious programmers" (the intended readers of language specifications) were probably familiar with mainstream programming languages of the time.

Before Java, most programming languages (C, C++, FORTRAN, Cobol, ...- counter-examples are SmallTalk and Lisp) shared the notion of a variable as a name for a memory chunk containing the binary representation of some information.

Java has some obvious similarities (syntax) with C++, but drastically differs on that notion : a variable refers to a value (of primitive type) or an object. An object is not contained in a variable.

So assigning an object in Java doesn't involve the duplication of that object.

It's a point to be stressed (heavily) when explaining Java to confused C++ programmers. And a simple way to do it is to say Java variables contain references, which are like C++ pointers containing addresses of objects (and are magically de-referenced without a star).

But it's only a way to illustrate concepts of Java with a metaphor, borrowing from a different world. It only helps if you know C++ beforehand. Having to teach pointers first makes the thing more complicated.

The basic explanation is

  • objects exist somewhere in the memory space,
  • references indicate where they are,

Actually pointers are not a "very hard" subject (addresses as first class data). The beginner's difficulties come from the algorithmic side of linked data structures.

$\endgroup$
1
$\begingroup$

This is too long to be a comment:

Java is a pass by value language. You must understand that what variables store in Java. Primitives store their values directly. Object types store heap memory addresses. In either case, when you pass that an argument to a function that argument is evaluated, and then it is assigned to the function's parameter and it behaves like a local variable.

So, if you are passing a variable to a function the evaluation process causes a copy of the bit pattern it is storing to be made. In the case of an object, that's a copy of the memory address. This is why I carefully explain the idea of memory address to my beginning programming students. Python operates similarly, but it has no primitive types. All Python data are objects stored on the heap.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.