我很难理解对象引用在Java中是如何工作的?

我很难理解对象引用在Java中是如何工作的?,java,oop,reference,Java,Oop,Reference,我最初理解引用的方式是,它们只是内存引用,保存了它们所保存的实际对象的内存位置。不过,下面的代码及其输出让我感到困惑。在这里您可以看到一个简单的类管理器的实现 我在第一行创建了一个Man对象,引用名为peter。彼得本身只是一个记忆位置,对吗?所以,人应该只是将对象存储在它所在的内存位置 但当我把另一个人的名字指定给彼得,后来又改了彼得的名字,那个人却不知道,于是打印了他的名字。这怎么可能,因为它存储了peter的内存引用?它不应该跟随对它所做的更改吗 public class Testing

我最初理解引用的方式是,它们只是内存引用,保存了它们所保存的实际对象的内存位置。不过,下面的代码及其输出让我感到困惑。在这里您可以看到一个简单的类管理器的实现

我在第一行创建了一个Man对象,引用名为peter。彼得本身只是一个记忆位置,对吗?所以,人应该只是将对象存储在它所在的内存位置

但当我把另一个人的名字指定给彼得,后来又改了彼得的名字,那个人却不知道,于是打印了他的名字。这怎么可能,因为它存储了peter的内存引用?它不应该跟随对它所做的更改吗

public class Testing {

  public static void main(String[] args) {
    Man peter = new Man("brown", 182, 78000, "Peter");
    Man person = peter;
    peter = new Man("brown", 182, 78000, "Leonard");
    System.out.println(person.name);
  }
}

class Man {

   String hairColor;
   int height;
   double salary;
   String name;

   public Man()
   {
     hairColor = "brown";
     height = 180;
     salary = 50500.5;
     name = "John";
   }
   public Man(String hair, int high, double pay, String nam)
   {
        this.height = high;
        this.hairColor = hair;
        this.salary = pay;
        this.name = nam;
   }
}
它的工作原理如下:

Man peter = new Man("brown", 182, 78000, "Peter");
意味着你在内存中有了一个新的位置,这个位置有这些值

Man person = peter;
意味着这个人有相同的指向彼得记忆的指针

peter = new Man("brown", 182, 78000, "Leonard");
您使用新值将指针区域更改为新位置。

其工作原理如下:

Man peter = new Man("brown", 182, 78000, "Peter");
意味着你在内存中有了一个新的位置,这个位置有这些值

Man person = peter;
意味着这个人有相同的指向彼得记忆的指针

peter = new Man("brown", 182, 78000, "Leonard");
您使用新值将指针区域更改为新位置。

此处:

Man peter = new Man("brown", 182, 78000, "Peter");
创建名为Peter的Man对象

Man person = peter;
创建另一个指向上面创建的对象的变量

peter = new Man("brown", 182, 78000, "Leonard");
创建另一个名为Leonard的人,然后peter变量指向新的第二个对象

注意:此人没有指向彼得。它指向内存中的Man对象

将另一个内存地址放入peter变量不会更改您创建的初始对象。

此处:

Man peter = new Man("brown", 182, 78000, "Peter");
Man peter = new Man("brown", 182, 78000, "Peter");
Man person = peter;
peter = new Man("brown", 182, 78000, "Leonard");
创建名为Peter的Man对象

Man person = peter;
创建另一个指向上面创建的对象的变量

peter = new Man("brown", 182, 78000, "Leonard");
创建另一个名为Leonard的人,然后peter变量指向新的第二个对象

注意:此人没有指向彼得。它指向内存中的Man对象

将另一个内存地址放入peter变量不会改变您创建的初始对象

Man peter = new Man("brown", 182, 78000, "Peter");
Man person = peter;
peter = new Man("brown", 182, 78000, "Leonard");
第一行将引用指定给名为Peter的对象,第二行将上一个对象引用指定给变量person

在第三行中,您创建了一个新对象,并将对该对象的引用指定给变量peter,这是一个全新的引用,而变量person仍然保留前一个对象的引用

如果你想在两个变量中都有名字Leonard,而不是创建一个新的对象,你可以在第三行

person.name = "Leonard";
第一行将引用指定给名为Peter的对象,第二行将上一个对象引用指定给变量person

在第三行中,您创建了一个新对象,并将对该对象的引用指定给变量peter,这是一个全新的引用,而变量person仍然保留前一个对象的引用

如果你想在两个变量中都有名字Leonard,而不是创建一个新的对象,你可以在第三行

person.name = "Leonard";
当你使用

= new Man
创建一个新对象。所以,当你使用时,彼得在看人1,人在看新人2

= new Man

创建一个新对象。所以peter在看Man 1,person在看new Man 2,把引用想象成内存地址。我希望这个例子能说明:

Man peter = new Man("brown", 182, 78000, "Peter");
// Create a new Man object which is placed in (for example) memory location 100
// Assign 100 to peter


Man person = peter;
// Assign 100 to person (copying it from peter)

peter = new Man("brown", 182, 78000, "Leonard");
// Create a new Man object which is placed in memory location 120
// 120 is assigned to peter

System.out.println(person.name);
// person still contains 100, so this prints out the details of the first object

将引用视为内存地址。我希望这个例子能说明:

Man peter = new Man("brown", 182, 78000, "Peter");
// Create a new Man object which is placed in (for example) memory location 100
// Assign 100 to peter


Man person = peter;
// Assign 100 to person (copying it from peter)

peter = new Man("brown", 182, 78000, "Leonard");
// Create a new Man object which is placed in memory location 120
// 120 is assigned to peter

System.out.println(person.name);
// person still contains 100, so this prints out the details of the first object

将两个对象都指向同一内存/位置,然后将另一个引用分配给第一个对象,这样它就不会影响旧内存数据。

将两个对象都指向同一内存/位置,然后将另一个引用分配给第一个对象,这样它就不会影响旧内存数据。

peter=新人创建了新的内存位置。现在已经创建了2个内存位置,比如100和200。 静止的人指向彼得的记忆位置100。所以它显示的是第一个构造函数名peter

如果要将nam值显示为m,请在下面的行指定中添加

人=彼得


System.out.printlnperson.name

With peter=新人创建了新的内存位置。现在已经创建了两个内存位置,比如100和200。 静止的人指向彼得的记忆位置100。所以它显示的是第一个构造函数名peter

如果要将nam值显示为m,请在下面的行指定中添加

人=彼得


System.out.printlnperson.name

这怎么可能,因为它存储了peter的内存引用?那没有任何意义。您已经了解变量保留对对象的引用,然后您突然期望它不会这样做,而是保留对另一个变量的引用?为什么?请检查这个问题是否有助于您理解这一点:既然它存储了peter的内存引用,那么这是怎么回事?那没有任何意义。你已经了解瓦里亚了
bles保留了一个对对象的引用,然后突然期望它不会这样做,而是保留了对另一个变量的引用?为什么?请检查这个问题是否有助于你理解这一点:谢谢,这使它更清楚。接下来的问题是:这是如何处理原语的?假设你有int a=3;int b=a;a=5;b是在a中存储数字的值而不是变量引用本身吗?原语不是通过引用访问的。因此,分配的功能与您在那里看到的完全相同。A得3分,b得3分,A得5分,b保持为3分。谢谢,这使它更清晰了。接下来的问题是:这是如何处理原语的?假设你有int a=3;int b=a;a=5;b是在a中存储数字的值而不是变量引用本身吗?原语不是通过引用访问的。因此,分配的功能与您在那里看到的完全相同。A得3分,b得3分,A得5分,b保持为3分。谢谢,这使它更清晰了。接下来的问题是:这是如何处理原语的?假设你有int a=3;int b=a;a=5;b是在a中存储数字的值,而不是变量引用本身吗?@Elmer原语不指向内存。它们只是价值观。没有他们的参考资料。这就是为什么java区分堆内存中的引用类型对象和基元类型纯值的原因,无论是在堆上的对象内还是在本地堆栈上。@Elmer我欣赏快速恢复并接受btw-谢谢,这使它更清楚了。接下来的问题是:这是如何处理原语的?假设你有int a=3;int b=a;a=5;b是在a中存储数字的值,而不是变量引用本身吗?@Elmer原语不指向内存。它们只是价值观。没有他们的参考资料。这就是为什么java区分堆内存中的引用类型对象和基元类型纯值的原因,无论是在堆上的对象内还是在本地堆栈上。@Elmer我欣赏快速恢复并接受btw-