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

69 c# java variables reference object

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

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

例:

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

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

Jon*_*eet 153

(为了清楚起见,我在这里给出的解释是特定于Java和C#.不要认为它适用于其他语言,尽管它可能有点.)

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

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

这有帮助吗?

值类型和引用类型之间的差异是写在纸上的内容.例如,这里:

int x = 12;
Run Code Online (Sandbox Code Playgroud)

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

Dog myDog = new Dog();
Run Code Online (Sandbox Code Playgroud)

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

用非类比术语:

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

  • @Pshemo:不,不一定.例如,我可能会被要求多次地址,并且每次*可能*被写在同一张纸上.或者,把它想象成一个`GetJonsAddress`方法 - 我返回的是*值*(引用)......调用者用它做什么对我来说无关紧要.我无法返回一个新变量 - 我返回值.来电者*可以*在一张纸上写下来,但他们可能不会. (5认同)
  • @Pshemo:在该代码示例中,有两个变量、两个相等的值(两次相同的引用)和一个 Dog 对象。把引用想象成一个数字——如果你有 `int x = 15; int y = x;` 你有一个还是两个?:) (3认同)
  • @Pshemo:回答我关于 `int` 变量的问题,我会告诉你关于引用的信息:) (2认同)

The*_*kis 29

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


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

价值类型规则:

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

参考类型规则:

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

  • +1:我相信这个答案更好地描述了参考类型的细微差别而不是与纸张类比. (6认同)
  • @Smollet 好吧,是的。既然 OP 提出了要求,显然对他/她(以及可能最终来到这里的其他人)来说并不是那么简单。我相信人们可以在更短的答案中给出一个更简单的类比,但我个人发现上述所有要点都足够重要,可以包括在内。 (2认同)

Edg*_*ere 7

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

一个对象就是......
它就像世界上任何物理的东西,一个可以自己识别并具有与其他"东西"区别的重要属性的"东西".就像你知道一只狗是一只狗,因为它吠叫,移动它的尾巴,如果扔掉它就去追球.

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

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

现在为了编程,以C++方式的示例

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

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

&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)
Run Code Online (Sandbox Code Playgroud)

Ana 本身是存储名为"Ana"的人的属性的变量


Cor*_*ica 6

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

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

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

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

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