简体   繁体   中英

How do I create a pointer variable to a reference variable in Java?

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).

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;
  }
}

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM