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

2022-08-31 12:55:53

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

例如:它们都指向某个类型,并且它们必须都持有值(当然,除非你有临时的null-able类型),但是它们的函数和实现究竟有什么不同呢?

例:

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

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


答案 1

(为了清楚起见,我在这里给出的解释是特定于Java和C#的。不要以为它适用于其他语言,尽管它的某些部分可能。

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

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

这有帮助吗?

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

int x = 12;

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

Dog myDog = new Dog();

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

用非类比术语来说:

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

答案 2

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


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

值类型的规则:

  • 你怀里抱着一个装满空气的气球。(值类型变量存储对象。
  • 您必须始终只握住一个气球。(值类型不为 null。
  • 当别人想要你的气球时,他们可以炸毁自己的气球,然后把它抱在怀里。(在值类型中,将复制对象。
  • 两个人不能拿着同一个气球。(不共享值类型。
  • 如果你想拿着一个不同的气球,你必须弹出你已经拿着的气球,然后抓住另一个。(值类型对象在替换时将被销毁。

参考类型的规则:

  • 你可以拿着一根绳子,通向一个充满氦气的气球。(引用类型变量存储对对象的引用。
  • 您可以握住一根绳子,或者根本不拿一根绳子。(引用类型变量可为 null。
  • 当别人想要你的气球时,他们可以得到自己的一根绳子,并把它绑在和你一样的气球上。(在引用类型中,引用是复制的。
  • 多个人可以拿着绳子,这些绳子都通向同一个气球。(可以共享引用类型对象。
  • 只要至少有一个人仍然拿着绳子到一个特定的气球上,气球就是安全的。(只要引用类型对象可访问,它就处于活动状态。
  • 对于任何一个特定的气球,如果每个人都最终放开它,那么那个气球就会飞走,没有人能再到达它了。(引用类型对象在某些时候可能会变得无法访问。
  • 在游戏结束前的某个稍后点,由于大气压力,丢失的气球可能会自行弹出。(无法访问的对象符合垃圾回收的条件,这是非确定性的。