variables,对象和引用之间有什么区别?

到底什么是variables对象引用之间的区别?

例如:它们都指向某种types,并且它们都必须具有值(除非有临时的无效types),但是它们的function和实现又是如何不同?

例:

Dog myDog = new Dog(); //variable myDog that holds a reference to object Dog int x = 12; //variable x that hold a value of 12 

他们有相同的概念,但他们有什么不同呢?

(只是要清楚,我在这里给出的解释是特定于Java和C#。不要以为它适用于其他语言,尽pipe它可能位)。

我喜欢用比喻告诉别人我住的地方。 我可能会在一张纸上写下我的地址:

  • variables就像一张纸。 它具有价值,但它本身并不是价值。 你可以把任何东西划掉,然后写一些别的东西。
  • 我写在纸上的地址就像一个参考。 这不是我的房子,但它是一种导航到我家的方式。
  • 我的房子本身就像一个物体。 我可以给出多个对同一个对象的引用,但是只有一个对象。

这有帮助吗?

值types和引用types之间的区别就是写在纸上的东西。 例如,在这里:

 int x = 12; 

就像有一张纸上写着数字12直接。 鉴于:

 Dog myDog = new Dog(); 

不会将Dog对象内容本身写在纸上 – 它会创build一个新的Dog ,然后在该纸上写入对该Dog的引用。

用非类比的术语来说:

  • 一个variables表示内存中的存储位置。 它有一个名称,可以在编译时引用它,在执行时它有一个值,它总是与编译时types兼容。 (例如,如果您有一个Buttonvariables,则该值将始终是对Buttontypes或某个子types的对象的引用,或者是null引用。
  • 一个对象是一种独立的实体。 重要的是,一个variables或任何expression式的值永远不是一个对象,只是一个引用。 一个对象有效地包括:
    • 田野(国家)
    • types引用(永远不会改变对象的生命周期)
    • 监视器(用于同步)
  • 引用是一个用于访问对象的值 – 例如调用它的方法,访问字段等. 运营商。 例如,如果foo是一个Personvariables,则foo.getAddress().getLength()将取参考引用的对象的值foo (引用)并调用getAddress() 。 结果可能是一个String引用…然后我们调用引用所引用的对象上的getLength()

在解释这些概念时,我经常用下面的类比。


想象一下,一个物体是一个气球。 一个variables是一个人。 每个人都是价值型团队或参考型团队。 他们都按照以下规则玩一个小游戏:

值types的规则:

  • 你抱着一个充满空气的气球。 (值typesvariables存储对象。)
  • 你必须始终持有一个气球。 (值types不可为空)
  • 当别人想要你的气球的时候,他们可以炸毁自己的气球,并把它们抱在怀里。 (在值types中,对象被复制。)
  • 两个人不能拥有同一个气球。 (值types不共享。)
  • 如果你想要一个不同的气球,你必须popup一个你已经拿着的另一个。 (值types对象在被​​replace时被销毁。)

参考types的规则:

  • 你可能握住一条导致充满氦气的气球的弦。 (引用typesvariables存储对象的引用。)
  • 你可以拿一根绳子,或者根本没有一根绳子。 (引用typesvariables是可空的。)
  • 当别人想要你的气球时,他们可以得到他们自己的一串,并把它绑在同一个气球上。 (在引用types中,引用被复制。)
  • 多人可以持有所有导致相同的气球的string。 (引用types的对象可以共享。)
  • 只要至less还有一个人将绳子固定在特定的气球上,气球就是安全的。 (只要引用types的对象可用,它就是活着的。)
  • 对于任何特定的气球,如果每个人都最终放弃它,那么气球就飞走了,没有人能够达到它了。 (引用types的对象可能在某个时候无法访问。)
  • 在比赛结束之前的某个时间点,丢失的气球可能由于大气压力而自行popup。 (无法访问的对象有资格进行垃圾回收,这是非确定性的。)

你可以把它想成一个回答问题。

一个对象是一个什么…
它就像世界上任何物质的东西一样,是一个可以自己识别的“物”,具有与其他“物”区别开来的重要属性。 就像你知道一只狗是一只狗,因为它吠叫,移动它的尾巴,如果你扔它的球。

一个variables是一个…
就像你看自己的手一样。 每个人都是一只手。 他们的皮肤有手指,指甲和骨头,但你知道一个是你的左手,另一个是正确的。 也就是说,你可以有两种相同types/种类的“东西”,但每一种东西都可以有自己的不同,可以有不同的价值。

参考是一个地方…
如果你看一条街上的两座房子,虽然他们有自己的门面,但是你可以通过他们唯一的一个地址来find每一个房子,也就是说,如果你远离三个街区或者在另一个国家,你可以告诉房子的地址,因为他们仍然会在那里离开他们,即使你不能直接指出他们。

现在以编程为例,以C ++的方式举例说明

 class Person{...} Person Ana = new Person(); //An object is an instance of a class(normally) 

也就是说,安娜是一个人,但她有独特的属性,区别于另一个人。

 &Ana //This is a reference to Ana, that is to say, a "where" does the variable //"Ana" is stored, wether or not you know it's value(s) 

Ana本身是存储名为“Ana”的人的属性的variables

乔恩的答案非常适合用类比来解决。 如果更具体的措词对你有用,我可以介入。

我们从一个variables开始。 一个variables是一个[named]事物,它包含一个值。 例如, int x = 3定义了一个名为x的variables,其中包含整数3.如果我随后使用赋值x=4 ,则x现在包含整数4.关键是我们没有replacevariables。 我们没有一个新的“variablesx现在的值是4”,我们只是用新值replace了x的值。

现在让我们移动到对象。 对象是有用的,因为通常你需要从一个地方引用一个“东西”。 例如,如果您在编辑器中打开了一个文档,并希望将其发送到打印机,那么只有一个文档(由编辑器和打印机引用)会很好。 这样可以节省您不必复制的次数。

但是,因为您不想多次复制它,所以我们不能只将对象放在variables中。 variables保存一个值,所以如果两个variables保存在一个对象上,他们必须做两个副本,每个variables一个。 参考是解决这个问题的中间人。 引用是很小的,很容易复制的值可以存储在variables中。

因此,在代码中,当您inputDog dog = new Dog() ,新运算符将创build一个新的Dog对象,并返回一个对该对象的引用,以便将其分配给一个variables。 然后赋值给一个引用的值给新创build的对象。

新的狗()将实例化一个对象狗ie)它将为该对象创build一个内存。 您需要访问该variables来操作某些操作。 为此,你需要一个参考是狗myDog。 如果你尝试打印对象,它将打印一个不可读的值,这个值只是地址。

  myDog -------> new Dog().