2014-10-28 132 views
2

我想創建一個變量,指向不同的引用變量指向的任何內容,以便如果我更改引用變量指向的位置,指針變量也會自動指向該新位置。如何在Java中爲參考變量創建指針變量?

例如,假設我認爲我最喜歡的書是當地圖書館最喜歡的書。如果我的圖書館改變他們最喜歡的書,我會自動認爲這是我最喜歡的書。

下面是一些代碼來證明我的意思:

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. 

在上面的代碼,改變什麼libraryFavourite點不會自動改變什麼myFavourite點。它保持指向littleWomen

我明白爲什麼上面的代碼不起作用,因爲我在說我「想要」它。據我所知,參考變量包含內存地址,因此myFavourite = libraryFavourite只是將libraryFavourite指向的內存地址指定爲myFavourite,因此未來更改爲libraryFavourite不會更改myFavourite。我只包含上面的代碼來幫助闡明我想要的行爲,但明白我需要一種不同的方法來實現。

This鏈接有關別名類別的討論(和收到的答案基本上是它不能完成)。然而,別名並不完全是我想要做的,因爲我想要自由地改變myFavourite來停止指向圖書館最喜歡的書,而是指向其他的東西(例如,我最近發現的一些新書,愛上了)。

+1

這被故意排除在語言之外,如許多其他語言一樣。 – user2357112 2014-10-28 01:04:37

+0

你的用例是什麼? – 2014-10-28 01:06:18

+1

這是直接關係到[Java是「通過引用傳遞」還是「按值傳遞」?](http://stackoverflow.com/q/40480/1065197) – 2014-10-28 01:10:44

回答

3

要實現這樣的行爲,您必須將引用存儲在對象中而不是本地值。 它不應該像你期待的那樣工作。變量只是指向對象,如果你改變它,你只需要指向不同的對象 - 你也不能改變根對象!

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

libraryFavorite.set(dracula); 

//now myFavorite.get also points to dracula 

和收藏只是一個參照物座:

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

@Quincunx沒問題。此外,這些解決方案是完全不同的 - 你允許建立書樹 - 我不確定這是最好的主意。 – 2014-10-28 01:17:41

+0

如果我想以與書籍相同的方式使用libraryFavourite和myFavourite(以便我可以執行諸如'myFavourite.turnPage()')之類的操作,您是否建議我將'Favourite'作爲Book的子類? 這種解決方法似乎很笨重,但也許沒有更好的解決方法,所以感謝您的建議。 – silph 2014-10-28 01:20:58

+2

@silph我認爲這是個不好的主意,因爲最喜歡的位置不是書。如果它簡化了你的代碼比它可以是一個選項,但我會稱它比「解決方案」更「解決方法」:) – 2014-10-28 01:23:14

0

沒有辦法做到這一點。將參考(referenceA)分配給另一個參考(referenceB)時。 referenceA複製referenceB的內存地址,就是這樣。 referenceA忘記referenceB。如果referenceB指向另一個內存地址,則該更改不適用於referenceA。

+0

是的,我意識到這是參考變量的工作方式。這是問題:)我想知道是否有不同的方式來解決這個問題(比如我可能沒有意識到某些Java功能,或者我沒有意識到的一些聰明技巧)。 – silph 2014-10-28 01:16:52

0

解決方法是讓您的書籍類有一個構造函數,將另一本書作爲參數,在第一次初始化它時使用它,然後改變它。也許你會想要一個子類,所以你可以把最喜歡的作爲Book。其實我不建議這樣做,而不是有本書getter和剛做favourite.get().whateverYouWantToDoWithMe();

然後,你可以這樣做:

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 

一個實現這一點的同時仍然允許Book爲不可變的可行方式如下:

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 
} 

然後,你可以這樣做:

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 
+0

謝謝你寫這個;它有助於澄清我爲什麼喜歡@ JakubKubrynski的回答,相反。我喜歡你的方式,因爲我可以使用'myFavourite'和'libraryFavourite'作爲'Book's(即使用'Book's的方法),我喜歡Jakub的回答,因爲它強調了我打算的事實使用這種不尋常/奇怪的「指針」行爲。 – silph 2014-10-28 01:38:06