变量、对象和引用之间的区别是什么?



变量对象引用到底有什么区别?

例如:它们都指向某种类型,并且它们都必须保存值(当然,除非您拥有临时可空类型),但是它们的函数和实现彼此之间究竟有何不同?

的例子:

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#的。不要认为它适用于其他语言,尽管它的某些部分可能适用。

我喜欢用一个比喻来告诉别人我住在哪里。我可以把我的地址写在一张纸上:
  • 变量就像一张纸。它保存一个值,但它本身不是这个值。你可以把那里的东西划掉,然后写一些别的东西。
  • 我写在纸上的地址就像一个参考。这不是我的房子,但这是一种导航到我家的方式。
  • 我的房子本身就像一个物体。我可以给出对同一个对象的多个引用,但只有一个对象。

有帮助吗?

值类型和引用类型的区别在于写在纸上的内容。例如:

int x = 12;

就像一张直接写了数字12的纸。而:

Dog myDog = new Dog();

不把Dog对象的内容本身写在纸上——它创建了一个新的Dog,然后在纸上写了一个对Dog的引用。

在非类比条件下:

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

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


想象一个物体是一个气球。变量是一个人。每个人要么在值类型团队中,要么在引用类型团队中。他们都玩了一个小游戏,规则如下:

值类型的规则:
    你抱着一个充满空气的气球。(值类型变量存储对象)
  • 你必须一直拿着一个气球。(值类型不可为空)
  • 当别人想要你的气球时,他们可以自己吹一个一模一样的,然后把它抱在怀里。(在值类型中,对象被复制)两个人不能拿同一个气球。(值类型不共享)
  • 如果你想拿一个不同的气球,你必须打破你已经拿着的一个,然后抓住另一个。(值类型对象在被替换时被销毁)
引用类型的规则:
    你可以抓住一根绳子,它通向一个充满氦气的气球。(引用类型变量存储对对象的引用)
  • 你可以拿一根绳子,也可以不拿绳子。(引用类型变量可为空)
  • 当别人想要你的气球时,他们可以自己找一根绳子,把它绑在和你一样的气球上。(在引用类型中,引用被复制)
  • 多个人可以拿着通往同一个气球的绳子。(引用类型的对象可以共享)
  • 只要至少有一个人还在握着气球的绳子,气球就是安全的。
  • (一个引用类型的对象,只要它是可访问的,它就是活的。)
  • 对于任何一个特定的气球,如果每个人最终都放开它,那么气球就会飞走,没有人能再到达它。(引用类型对象可能在某些时候变得不可访问)
  • 在游戏结束前的某个时间点,由于大气压力,一个丢失的气球可能会自己爆开。(不可达对象有资格进行垃圾收集,这是不确定的。)

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

对象是什么?
它就像世界上的任何物理事物一样,一个"事物"本身是可识别的,并且具有区别于其他"事物"的重要属性。就像你知道狗是狗,因为它会叫,如果你扔球,它会动尾巴,追球。


就像你看着自己的手。每一只手本身就是一只手。它们的皮肤里有手指、指甲和骨头,但你知道一只是左手,另一只是右手。也就是说,你可以有两个相同类型/类型的"东西",但每一个都可以以自己的方式不同,可以有不同的值。


如果你看一条街上的两栋房子,虽然它们都有自己的门面,但你可以通过它们唯一的地址到达每一栋房子,这意味着,如果你离得很远,比如三个街区远,或者在另一个国家,你可以说出房子的地址,因为它们仍然在你离开的地方,即使你不能直接指向它们。

现在为了编程的缘故,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"的人的属性的变量

Jon的回答非常适合类比。如果更具体的措辞对你有用,我可以帮忙。

让我们从一个变量开始。变量是一个包含值的[命名]事物。例如,int x = 3定义了一个名为x的变量,其中包含整数3。如果我接着赋值,x=4, x现在包含整数4。关键是我们没有替换变量。我们没有一个新的"变量x的值现在是4",我们只是用一个新值替换了x的值。

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

然而,因为你不想复制它多次,所以我们不能把对象放在变量中。变量保存一个值,所以如果两个变量保存一个对象,它们必须创建两个副本,每个变量一个。引用是解决这个问题的中介。引用是小的,容易复制的值,可以存储在变量中。

因此,在代码中,当您键入Dog dog = new Dog()时,new操作符创建一个新的Dog对象,并返回该对象的引用,以便将其赋值给变量。然后赋值给dog一个引用到你新创建的对象的值。

new Dog()将实例化一个对象Dog(),它将为该对象创建一个内存。您需要访问该变量来操作一些操作。为此,您需要一个引用,即Dog myDog。如果你试图打印对象,它将打印一个不可读的值,除了地址之外什么都没有。

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

相关内容

最新更新