2014-10-28 88 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