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

时间:2015-08-14 12:30:18

标签: java c# variables object reference

变量对象参考之间究竟有什么区别?

例如:它们都指向某种类型,并且它们都必须保存值(当然除非你有临时的无效类型),但它们的功能和实现究竟是如何彼此不同的呢?

示例:

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

他们有相同的概念,但它们有何不同?

5 个答案:

答案 0 :(得分:148)

(为了清楚起见,我在这里给出的解释是针对Java和C#的。不要假设它适用于其他语言,虽然它可能有点。)

我喜欢用某种方式告诉某人我居住的地方。我可以在一张纸上写下我的地址:

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

这有帮助吗?

值类型和引用类型之间的区别在于写在纸上。例如,这里:

int x = 12;

就像有一张纸,上面写着12号。鉴于:

Dog myDog = new Dog();

不会在纸上写下Dog对象内容 - 它会创建一个新的Dog,然后在该纸上写一条对狗的引用。

以非类比术语:

  • 变量表示内存中的存储位置。它有一个名称,您可以在编译时引用它,并且在执行时它有一个值,它始终与其编译时类型兼容。 (例如,如果您有Button变量,则该值将始终是对Button类型或某个子类 - 或null引用的对象的引用。)
  • 对象是一种独立的实体。重要的是,变量或任何表达式的值从不一个对象,只是一个引用。对象实际上包括:
    • 字段(州)
    • 类型引用(永远不会改变对象的生命周期)
    • 监视器(用于同步)
  • 引用是用于访问对象的值 - 例如调用方法,访问字段等。您通常使用.运算符导航引用。例如,如果fooPerson变量,则foo.getAddress().getLength()将获取foo(引用)的值,并在该引用的对象上调用getAddress()是指。结果可能是String引用...然后我们会在 引用引用的对象上调用getLength()

答案 1 :(得分:29)

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

想象一个物体是一个气球。变量是一个人。每个人都在值类型团队或引用类型团队中。他们都按照以下规则玩一个小游戏:

值类型的规则

  • 你抱着一个充满空气的气球。 (值类型变量存储对象。)
  • 你必须一直拿着一个气球。 (值类型不可为空。)
  • 当别人想要你的气球时,他们可以炸毁他们自己的气球,并把它抱在怀里。 (在值类型中,复制对象。)
  • 两个人不能握住同一个气球。 (不共享值类型。)
  • 如果你想要拿一个不同的气球,你必须弹出你已经持有的气球并抓住另一个气球。 (替换时会破坏值类型对象。)

参考类型的规则

  • 你可以拿一根绳子,通向一个充满氦气的气球。 (引用类型变量存储对象的引用。)
  • 你可以拿一根绳子,或根本不拿绳子。 (引用类型变量可以为空。)
  • 当别人想要你的气球时,他们可以拿出自己的一根绳子并将它系在同一个气球上。 (在引用类型中,复制引用。)
  • 多人可以握住所有通往同一气球的弦乐。 (可以共享引用类型对象。)
  • 只要至少有一个人仍将绳子固定在特定的气球上,气球就是安全的。 (只要可以访问引用类型对象,它就是活动的。)
  • 对于任何特定的气球,如果每个人最终放下它,那么那个气球飞走了,没有人能再到达它。 (某个时候参考类型对象可能无法访问。)
  • 在游戏结束之前的某个时间点,由于大气压力,丢失的气球可能会自行弹出。 (无法访问的对象有资格进行垃圾回收,这是非确定性的。)

答案 2 :(得分:7)

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

对象是......
它就像世界上任何物质的东西一样,""它本身是可识别的,具有与其他物品区别开来的重要特性。 就像你知道一只狗是一只狗,因为它会吠叫,移动它的尾巴,如果扔掉它就去追球。

变量是......
就像你自己动手一样。每一个都是一只手。它们在皮肤内有手指,指甲和骨头,但你知道一个是左手,另一个是右手。 也就是说,你可以有两个东西"相同类型/种类,但每个人可能有所不同,可以有不同的价值。

参考是......
如果你看一下街道上的两栋房子,虽然它们有自己的立面,但你可以通过一个独特的地址到达每个房屋,这意味着,如果你像远在三个街区或另一个地方那么远国家,你可以告诉房子的地址,因为他们仍然会在你离开他们的地方,即使你不能直接指出他们。

现在出于编程的缘故,以C ++方式举例

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

也就是说,Ana是一个人,但她有独特的属性,使她与另一个人区别开来。

&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"

的人的属性的变量

答案 3 :(得分:6)

Jon的回答非常适合从类比中接近它。如果更具体的措辞对你有用,我可以投入。

让我们从变量开始。变量是包含值的[named]事物。例如,int x = 3定义了一个名为x的变量,它包含整数3.如果我然后用赋值x=4跟进它,x现在包含整数4.关键是我们没有& #39; t替换变量。我们没有新的"变量x,其值现在为4,"我们只是用新值替换了x的值。

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

但是,由于您不想多次复制它,我们无法将对象放入变量中。变量保持一个值,因此如果两个变量保持在一个对象上,它们必须制作两个副本,每个变量一个副本。引用是解决此问题的中间人。引用是一些小的,易于复制的值,可以存储在变量中。

因此,在代码中,当您键入Dog dog = new Dog()时,new运算符会创建一个新的Dog Object,并返回对该对象的Reference,以便将其分配给变量。然后,赋值为dog提供对新创建的对象的引用值。

答案 4 :(得分:3)

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

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