2

I would like to make a variable that points to whatever a different reference variable is pointing to, so that if I change where the reference variable points, the pointer variable automatically points to that new place, too.

For example, suppose I consider my favourite book to be whatever my local library's favourite book is. If my library changes what their favourite book is, I automatically consider that to be my favourite book.

Here is some code to demonstrate what I mean:

Book littleWomen = new Book("Little Women");
Book dracula = new Book("Dracula");

Book libraryFavourite = litteWomen;
Book myFavourite = libraryFavourite;  //myFavoutie is now littleWomen

libraryFavourite = dracula;   //i want myFavourite to update to point to dracula, now.

In the above code, changing what libraryFavourite points to doesn't automatically change what myFavourite points to. It stays pointing at littleWomen.

I understand why the above code doesn't work as I'm saying I "want" it to. I understand that reference variables hold memory addresses, and therefore myFavourite = libraryFavourite just assigns the memory address that libraryFavourite points to into myFavourite, and thus future changes to libraryFavourite doesn't change myFavourite. I only include the above code to help clarify the behaviour that I want, but understand I'll need a different approach to achieve.

This link talks about aliasing a class (and the answers received was basically that it can't be done). Aliasing isn't exactly what I want done, though, because I want to be free to change myFavourite to stop pointing to the library's favourite book, and instead to something else (such as, for example, some new book that I newly discovered and fell in love with).

10
  • 1
    This is deliberately excluded from the language, as in many, many other languages. Commented Oct 28, 2014 at 1:04
  • What is your use case? Commented Oct 28, 2014 at 1:06
  • 1
    This is directly related to Is Java “pass-by-reference” or “pass-by-value”? Commented Oct 28, 2014 at 1:10
  • @PM77-1, I was trying to teach another student in my progam the basics of objects and classes, and when we got to examples where I assigned a reference variable to another reference variable, she actually thought that this was how reference variables worked. This intrigued me, because I realized that I didn't know how to make this behaviour happen in Java, though I know it's possible in (say) C. Commented Oct 28, 2014 at 1:11
  • You may want to read this: javadude.com/articles/passbyvalue.htm Commented Oct 28, 2014 at 1:12

3 Answers 3

3

To achieve such behaviour you have to store references in objects instead of local values. It should never work as you're expecting. Variable just points to object, and if you change it you just make it points to different object - you cannot change also root object!

Favorite libraryFavorite = new Favorite(littleWomen);
Favorite myFavorite = libraryFavorite;

libraryFavorite.set(dracula);

//now myFavorite.get also points to dracula

and Favorite is just a reference holder:

public class Favorite {
  private Book book;

  public Favorite(Book book) {
    this.book = book;
  }

  public void set(Book newBook) {
    this.book = newBook;
  }

  public Book get() {
    return book;
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

@Quincunx no problem. Also those solutions are quite different - your allow building book trees - I'm not sure it's the best idea in this case.
If I wanted to use libraryFavourite and myFavourite the very same way as Books (so that I could do things like myFavourite.turnPage() ), do you recommend that I make Favourite a subclass of Book? This workaround seems clunky, but maybe there is no better workaround, so thanks for the suggestion.
@silph I think it's bad idea because favorite position is something else than a book. If it simplifies your code than it can be an option but I'll call it more "workaround" than "solution" :)
@silph Jakub's workaround is better. If you did make favourite a subclass of Book, you'd end up with some weird things that can happen. To do myFavourite.turnPage(), simply do myFavourite.get().turnPage(). For one example of something weird that can happen, what if we do myFavourite.set(myFavourite)?
0

There is not way to do that. When you assign a reference (referenceA) to another reference (referenceB). The referenceA copy the memory address of referenceB and that's it. referenceA forget about referenceB. If referenceB point to another memory address, that change doesn't apply to referenceA.

1 Comment

Yes, I realize that this is how reference variables work. This is the problem :) I was wondering if there was a different way to approach this (such as maybe some Java feature I'm unaware of, or some clever technique I'm unaware of).
0

A workaround would be to let your book class have a constructor that takes another book as an argument, use that the first time you initialize it, then mutate it. Perhaps you'd want a subclass for this, so you could treat the favourite as a Book. I'd actually recommend not doing that, instead have a getter for the book and just do favourite.get().whateverYouWantToDoWithMe();

Then you could do this:

Book littleWomen = new Book("Little Women");
Book dracula = new Book("Dracula");

Book libraryFavourite = new Book(littleWomen);
Book myFavourite = libraryFavourite;  //myFavourite is now littleWomen

libraryFavourite.setBook(dracula); //myFavourite is now dracula

One possible way to implement this while still allowing Book to be immutable is as follows:

public class ReferenceBook extends Book {
    private Book book;

    public ReferenceBook(Book book) {
        this.book = book;
    }
    public void setBook(Book book) {
        this.book = book;
    }
    public boolean equals(Object o){
        if (o instanceof Book) {
            return o.equals(book);
        }
        return false;
    }
    // and so on for other methods
}

Then you'd do this:

Book littleWomen = new Book("Little Women");
Book dracula = new Book("Dracula");

ReferenceBook libraryFavourite = new ReferenceBook(littleWomen);
Book myFavourite = libraryFavourite;  //myFavourite is now littleWomen

libraryFavourite.setBook(dracula); //myFavourite is now dracula

1 Comment

thank you for writing this; it helps clarify for me why I like @JakubKubrynski's answer, by contrast. I like your way here because I'm able to use myFavourite and libraryFavouriteas Books (ie using methods that Books have), and I like Jakub's answer because it emphasizes the fact that I am intending to use such unusual/strange "pointer" behaviour.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.