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

时间:2021-02-17 13:20:25

This question already has an answer here:

这个问题已经有了答案:

Exactly what are the differences between variables, objects, and references?

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

For example: they all point to some type, and they must all hold values (unless of course you have the temporary null-able type), but precisely how are their functions and implementations different from each other?

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

Example:

例子:

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

They have the same concepts, but how are they different?

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

5 个解决方案

#1


144  

(Just to be clear, the explanation I'm giving here is specific to Java and C#. Don't assume it applies to other languages, although bits of it may.)

我在这里给出的解释是针对Java和c#的。不要想当然地认为它适用于其他语言,尽管有些语言可能适用。

I like to use an analogy of telling someone where I live. I might write my address on a piece of paper:

我喜欢用比喻告诉别人我住在哪里。我可以把我的地址写在一张纸上:

  • A variable is like a piece of paper. It holds a value, but it isn't the value in itself. You can cross out whatever's there and write something else instead.
  • 变量就像一张纸。它拥有一个值,但它本身并不是这个值。你可以划掉任何东西,然后写点别的东西。
  • The address that I write on the piece of paper is like a reference. It isn't my house, but it's a way of navigating to my house.
  • 我在这张纸上写的地址就像一个参考。它不是我的房子,但它是我回家的一种方式。
  • My house itself is like an object. I can give out multiple references to the same object, but there's only one object.
  • 我的房子就像一个物体。我可以给出对同一个对象的多个引用,但是只有一个对象。

Does that help?

这有帮助吗?

The difference between a value type and a reference type is what gets written on the piece of paper. For example, here:

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

int x = 12;

is like having a piece of paper with the number 12 written on it directly. Whereas:

就像有一张纸,上面直接写着12。而:

Dog myDog = new Dog();

doesn't write the Dog object contents itself on the piece of paper - it creates a new Dog, and then writes a reference to the dog on that paper.

不要把狗的对象内容写在纸上——它会创建一条新的狗,然后在那张纸上给狗写一个参考。

In non-analogy terms:

non-analogy术语:

  • A variable represents a storage location in memory. It has a name by which you can refer to it at compile time, and at execution time it has a value, which will always be compatible with its compile-time type. (For example, if you've got a Button variable, the value will always be a reference to an object of type Button or some subclass - or the null reference.)
  • 变量表示内存中的存储位置。它有一个名称,您可以在编译时引用它,在执行时它有一个值,它总是与它的编译时类型兼容。(例如,如果您有一个Button变量,那么该值将始终是对类型为Button的对象或某个子类的引用——或null引用。)
  • An object is a sort of separate entity. Importantly, the value of a variable or any expression is never an object, only a reference. An object effectively consists of:
    • Fields (the state)
    • 字段(国家)
    • A type reference (can never change through the lifetime of the object)
    • 类型引用(在对象的生命周期中不能更改)
    • A monitor (for synchronization)
    • 监视器(同步)
  • 对象是一种独立的实体。重要的是,变量或任何表达式的值都不是对象,而是引用。对象有效地由:Fields(状态)、类型引用(在对象的生命周期内永远不会改变)、监视器(用于同步)组成
  • A reference is a value used to access an object - e.g. to call methods on it, access fields etc. You typically navigate the reference with the . operator. For example, if foo is a Person variable, foo.getAddress().getLength() would take the value of foo (a reference) and call getAddress() on the object that that reference refers to. The result might be a String reference... we then call getLength() on the object that that reference refers to.
  • 引用是用于访问对象的值,例如调用对象上的方法、访问字段等。操作符。例如,如果foo是一个Person变量,那么foo.getAddress(). getlength()将取foo(引用)的值,并在引用引用的对象上调用getAddress()。结果可能是字符串引用…然后我们在引用的对象上调用getLength()。

#2


28  

I often use the following analogy when explaining these concepts.

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


Imagine that an object is a balloon. A variable is a person. Every person is either in the value type team or in the reference type team. And they all play a little game with the following rules:

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

Rules for value types:

值类型的规则:

  • You hold in your arms a balloon filled with air. (Value type variables store the object.)
  • 你抱着一个充满空气的气球。(值类型变量存储对象。)
  • You must always be holding exactly one balloon. (Value types are not nullable.)
  • 你一定一直拿着一个气球。(值类型不为空。)
  • When someone else wants your balloon, they can blow up their own identical one, and hold that in their arms. (In value types, the object is copied.)
  • 当别人想要你的气球时,他们可以炸掉自己的气球,把它抱在怀里。(在值类型中,对象被复制。)
  • Two people can't hold the same balloon. (Value types are not shared.)
  • 两个人拿不开同样的气球。(值类型不共享。)
  • If you want to hold a different balloon, you have to pop the one you're already holding and grab another. (A value type object is destroyed when replaced.)
  • 如果你想拿一个不同的气球,你必须把你已经拿着的气球打开,再拿一个。(值类型对象在替换时被销毁。)

Rules for reference types:

引用类型的规则:

  • You may hold a piece of string that leads to a balloon filled with helium. (Reference type variables store a reference to the object.)
  • 你可以拿着一根绳子,绳子通向一个充满氦气的气球。(引用类型变量存储对对象的引用。)
  • You are allowed to hold one piece of string, or no piece of string at all. (Reference type variables are nullable.)
  • 您可以持有一个字符串,或者根本没有任何字符串。(引用类型变量为空。)
  • When someone else wants your balloon, they can get their own piece of string and tie it to the same balloon as you have. (In reference types, the reference is copied.)
  • 当别人想要你的气球时,他们可以得到自己的一根绳子,并把它绑在你的气球上。(在引用类型中,引用被复制。)
  • Multiple people can hold pieces of string that all lead to the same balloon. (Reference type objects can be shared.)
  • 多个人可以拿着几根绳子,这些绳子都通向同一个气球。(引用类型对象可以共享。)
  • As long as there is at least one person still holding the string to a particular balloon, the balloon is safe. (A reference type object is alive as long as it is reachable.)
  • 只要有至少一个人把绳子绑在一个特殊的气球上,气球就安全了。(一个引用类型对象只要是可达的,它就是活的。)
  • For any particular balloon, if everyone eventually lets go of it, then that balloon flies away and nobody can reach it anymore. (A reference type object may become unreachable at some point.)
  • 对于任何一个特定的气球,如果每个人最终都放手,那么气球就会飞走,再也没有人能够到它了。(引用类型对象在某些时候可能变得不可访问。)
  • At some later point before the game ends, a lost balloon may pop by itself due to atmospheric pressure. (Unreachable objects are eligible for garbage collection, which is non-deterministic.)
  • 在游戏结束前的某个时候,一个丢失的气球可能会因为气压的原因自行爆裂。(不可访问的对象有资格进行垃圾收集,这是不确定的。)

#3


7  

You can think of it like a answering questions.

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

An object is a what...
It's like any physical thing in the world, a "thing" which is recognizable by itself and has significant properties that distinguishes from other "thing". Like you know a dog is a dog because it barks, move its tail and go after a ball if you throw it.

A variable is a which...
Like if you watch your own hands. Each one is a hand itself. They have fingers, nails and bones within the skin but you know one is your left hand and the other the right one. That is to say, you can have two "things" of the same type/kind but every one could be different in it's own way, can have different values.

物体是什么……它就像世界上的任何物质一样,是一种“事物”,它本身是可以识别的,并且具有区别于其他“事物”的重要属性。就像你知道狗是狗一样,因为它会叫,如果你扔了它,它就会动它的尾巴,去追一个球。变量A是。就像你看着自己的手。每一个都是一只手。它们的皮肤里有手指、指甲和骨头,但你知道一个是左手,另一个是右手。也就是说,你可以有两个相同类型/类型的“事物”,但是每个事物都可以有不同的方式,可以有不同的价值。

A reference is a where...
If you look at two houses in a street, although they're have their own facade, you can get to each one by their one unique address, meaning, if you're far away like three blocks far or in another country, you could tell the address of the house cause they'll still be there where you left them, even if you cannot point them directly.

指的是……如果你看看两个房子在一个街,尽管他们有自己的外观,你可以通过一个唯一的地址,每一个的意思,如果你远像三个街区远或在另一个国家,你可以告诉房子的地址导致他们会依然存在,你就离开他们,即使你不能直接点。

Now for programming's sake, examples in a C++ way

现在为了编程,用c++的方式举例

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

That is to say, Ana is a person, but she has unique properties that distinguishes her from another person.

也就是说,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 itself is the variable for storing the properties of the person named "Ana"

Ana本身是用于存储名为“Ana”的人的属性的变量

#4


6  

Jon's answer is great for approaching it from analogy. If a more concrete wording is useful for you, I can pitch in.

琼恩的回答很好,用类比来解释。如果有一个更具体的措词对你有用,我可以帮忙。

Let's start with a variable. A variable is a [named] thing which contains a value. For instance, int x = 3 defines a variable named x, which contains the integer 3. If I then follow it up with an assignment, x=4, x now contains the integer 4. The key thing is that we didn't replace the variable. We don't have a new "variable x whose value is now 4," we merely replaced the value of x with a new value.

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

Now let's move to objects. Objects are useful because often you need one "thing" to be referenced from many places. For example, if you have a document open in an editor and want to send it to the printer, it'd be nice to only have one document, referenced both by the editor and the printer. That'd save you having to copy it more times than you might want.

现在我们来看看对象。对象是有用的,因为常常需要一个“东西”从许多地方引用。例如,如果在编辑器中打开一个文档并想将其发送到打印机,那么最好只有一个文档,由编辑器和打印机引用。这将节省您不得不拷贝它比您可能想要的更多次。

However, because you don't want to copy it more than once, we can't just put an object in a variable. Variables hold onto a value, so if two variables held onto an object, they'd have to make two copies, one for each variable. References are the go-between that resolves this. References are small, easily copied values which can be stored in variables.

但是,因为您不希望多次复制它,所以不能只将对象放入变量中。变量保存一个值,所以如果两个变量保存在一个对象上,它们就必须创建两个副本,每个变量对应一个副本。引用是解决这个问题的中间人。引用很小,很容易复制,可以存储在变量中。

So, in code, when you type Dog dog = new Dog(), the new operator creates a new Dog Object, and returns a Reference to that object, so that it can be assigned to a variable. The assignment then gives dog the value of a Reference to your newly created Object.

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

#5


3  

new Dog() will instantiate an object Dog ie) it will create a memory for the object. You need to access the variable to manipulate some operations. For that you need an reference that is Dog myDog. If you try to print the object it will print an non readable value which is nothing but the address.

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

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

#1


144  

(Just to be clear, the explanation I'm giving here is specific to Java and C#. Don't assume it applies to other languages, although bits of it may.)

我在这里给出的解释是针对Java和c#的。不要想当然地认为它适用于其他语言,尽管有些语言可能适用。

I like to use an analogy of telling someone where I live. I might write my address on a piece of paper:

我喜欢用比喻告诉别人我住在哪里。我可以把我的地址写在一张纸上:

  • A variable is like a piece of paper. It holds a value, but it isn't the value in itself. You can cross out whatever's there and write something else instead.
  • 变量就像一张纸。它拥有一个值,但它本身并不是这个值。你可以划掉任何东西,然后写点别的东西。
  • The address that I write on the piece of paper is like a reference. It isn't my house, but it's a way of navigating to my house.
  • 我在这张纸上写的地址就像一个参考。它不是我的房子,但它是我回家的一种方式。
  • My house itself is like an object. I can give out multiple references to the same object, but there's only one object.
  • 我的房子就像一个物体。我可以给出对同一个对象的多个引用,但是只有一个对象。

Does that help?

这有帮助吗?

The difference between a value type and a reference type is what gets written on the piece of paper. For example, here:

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

int x = 12;

is like having a piece of paper with the number 12 written on it directly. Whereas:

就像有一张纸,上面直接写着12。而:

Dog myDog = new Dog();

doesn't write the Dog object contents itself on the piece of paper - it creates a new Dog, and then writes a reference to the dog on that paper.

不要把狗的对象内容写在纸上——它会创建一条新的狗,然后在那张纸上给狗写一个参考。

In non-analogy terms:

non-analogy术语:

  • A variable represents a storage location in memory. It has a name by which you can refer to it at compile time, and at execution time it has a value, which will always be compatible with its compile-time type. (For example, if you've got a Button variable, the value will always be a reference to an object of type Button or some subclass - or the null reference.)
  • 变量表示内存中的存储位置。它有一个名称,您可以在编译时引用它,在执行时它有一个值,它总是与它的编译时类型兼容。(例如,如果您有一个Button变量,那么该值将始终是对类型为Button的对象或某个子类的引用——或null引用。)
  • An object is a sort of separate entity. Importantly, the value of a variable or any expression is never an object, only a reference. An object effectively consists of:
    • Fields (the state)
    • 字段(国家)
    • A type reference (can never change through the lifetime of the object)
    • 类型引用(在对象的生命周期中不能更改)
    • A monitor (for synchronization)
    • 监视器(同步)
  • 对象是一种独立的实体。重要的是,变量或任何表达式的值都不是对象,而是引用。对象有效地由:Fields(状态)、类型引用(在对象的生命周期内永远不会改变)、监视器(用于同步)组成
  • A reference is a value used to access an object - e.g. to call methods on it, access fields etc. You typically navigate the reference with the . operator. For example, if foo is a Person variable, foo.getAddress().getLength() would take the value of foo (a reference) and call getAddress() on the object that that reference refers to. The result might be a String reference... we then call getLength() on the object that that reference refers to.
  • 引用是用于访问对象的值,例如调用对象上的方法、访问字段等。操作符。例如,如果foo是一个Person变量,那么foo.getAddress(). getlength()将取foo(引用)的值,并在引用引用的对象上调用getAddress()。结果可能是字符串引用…然后我们在引用的对象上调用getLength()。

#2


28  

I often use the following analogy when explaining these concepts.

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


Imagine that an object is a balloon. A variable is a person. Every person is either in the value type team or in the reference type team. And they all play a little game with the following rules:

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

Rules for value types:

值类型的规则:

  • You hold in your arms a balloon filled with air. (Value type variables store the object.)
  • 你抱着一个充满空气的气球。(值类型变量存储对象。)
  • You must always be holding exactly one balloon. (Value types are not nullable.)
  • 你一定一直拿着一个气球。(值类型不为空。)
  • When someone else wants your balloon, they can blow up their own identical one, and hold that in their arms. (In value types, the object is copied.)
  • 当别人想要你的气球时,他们可以炸掉自己的气球,把它抱在怀里。(在值类型中,对象被复制。)
  • Two people can't hold the same balloon. (Value types are not shared.)
  • 两个人拿不开同样的气球。(值类型不共享。)
  • If you want to hold a different balloon, you have to pop the one you're already holding and grab another. (A value type object is destroyed when replaced.)
  • 如果你想拿一个不同的气球,你必须把你已经拿着的气球打开,再拿一个。(值类型对象在替换时被销毁。)

Rules for reference types:

引用类型的规则:

  • You may hold a piece of string that leads to a balloon filled with helium. (Reference type variables store a reference to the object.)
  • 你可以拿着一根绳子,绳子通向一个充满氦气的气球。(引用类型变量存储对对象的引用。)
  • You are allowed to hold one piece of string, or no piece of string at all. (Reference type variables are nullable.)
  • 您可以持有一个字符串,或者根本没有任何字符串。(引用类型变量为空。)
  • When someone else wants your balloon, they can get their own piece of string and tie it to the same balloon as you have. (In reference types, the reference is copied.)
  • 当别人想要你的气球时,他们可以得到自己的一根绳子,并把它绑在你的气球上。(在引用类型中,引用被复制。)
  • Multiple people can hold pieces of string that all lead to the same balloon. (Reference type objects can be shared.)
  • 多个人可以拿着几根绳子,这些绳子都通向同一个气球。(引用类型对象可以共享。)
  • As long as there is at least one person still holding the string to a particular balloon, the balloon is safe. (A reference type object is alive as long as it is reachable.)
  • 只要有至少一个人把绳子绑在一个特殊的气球上,气球就安全了。(一个引用类型对象只要是可达的,它就是活的。)
  • For any particular balloon, if everyone eventually lets go of it, then that balloon flies away and nobody can reach it anymore. (A reference type object may become unreachable at some point.)
  • 对于任何一个特定的气球,如果每个人最终都放手,那么气球就会飞走,再也没有人能够到它了。(引用类型对象在某些时候可能变得不可访问。)
  • At some later point before the game ends, a lost balloon may pop by itself due to atmospheric pressure. (Unreachable objects are eligible for garbage collection, which is non-deterministic.)
  • 在游戏结束前的某个时候,一个丢失的气球可能会因为气压的原因自行爆裂。(不可访问的对象有资格进行垃圾收集,这是不确定的。)

#3


7  

You can think of it like a answering questions.

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

An object is a what...
It's like any physical thing in the world, a "thing" which is recognizable by itself and has significant properties that distinguishes from other "thing". Like you know a dog is a dog because it barks, move its tail and go after a ball if you throw it.

A variable is a which...
Like if you watch your own hands. Each one is a hand itself. They have fingers, nails and bones within the skin but you know one is your left hand and the other the right one. That is to say, you can have two "things" of the same type/kind but every one could be different in it's own way, can have different values.

物体是什么……它就像世界上的任何物质一样,是一种“事物”,它本身是可以识别的,并且具有区别于其他“事物”的重要属性。就像你知道狗是狗一样,因为它会叫,如果你扔了它,它就会动它的尾巴,去追一个球。变量A是。就像你看着自己的手。每一个都是一只手。它们的皮肤里有手指、指甲和骨头,但你知道一个是左手,另一个是右手。也就是说,你可以有两个相同类型/类型的“事物”,但是每个事物都可以有不同的方式,可以有不同的价值。

A reference is a where...
If you look at two houses in a street, although they're have their own facade, you can get to each one by their one unique address, meaning, if you're far away like three blocks far or in another country, you could tell the address of the house cause they'll still be there where you left them, even if you cannot point them directly.

指的是……如果你看看两个房子在一个街,尽管他们有自己的外观,你可以通过一个唯一的地址,每一个的意思,如果你远像三个街区远或在另一个国家,你可以告诉房子的地址导致他们会依然存在,你就离开他们,即使你不能直接点。

Now for programming's sake, examples in a C++ way

现在为了编程,用c++的方式举例

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

That is to say, Ana is a person, but she has unique properties that distinguishes her from another person.

也就是说,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 itself is the variable for storing the properties of the person named "Ana"

Ana本身是用于存储名为“Ana”的人的属性的变量

#4


6  

Jon's answer is great for approaching it from analogy. If a more concrete wording is useful for you, I can pitch in.

琼恩的回答很好,用类比来解释。如果有一个更具体的措词对你有用,我可以帮忙。

Let's start with a variable. A variable is a [named] thing which contains a value. For instance, int x = 3 defines a variable named x, which contains the integer 3. If I then follow it up with an assignment, x=4, x now contains the integer 4. The key thing is that we didn't replace the variable. We don't have a new "variable x whose value is now 4," we merely replaced the value of x with a new value.

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

Now let's move to objects. Objects are useful because often you need one "thing" to be referenced from many places. For example, if you have a document open in an editor and want to send it to the printer, it'd be nice to only have one document, referenced both by the editor and the printer. That'd save you having to copy it more times than you might want.

现在我们来看看对象。对象是有用的,因为常常需要一个“东西”从许多地方引用。例如,如果在编辑器中打开一个文档并想将其发送到打印机,那么最好只有一个文档,由编辑器和打印机引用。这将节省您不得不拷贝它比您可能想要的更多次。

However, because you don't want to copy it more than once, we can't just put an object in a variable. Variables hold onto a value, so if two variables held onto an object, they'd have to make two copies, one for each variable. References are the go-between that resolves this. References are small, easily copied values which can be stored in variables.

但是,因为您不希望多次复制它,所以不能只将对象放入变量中。变量保存一个值,所以如果两个变量保存在一个对象上,它们就必须创建两个副本,每个变量对应一个副本。引用是解决这个问题的中间人。引用很小,很容易复制,可以存储在变量中。

So, in code, when you type Dog dog = new Dog(), the new operator creates a new Dog Object, and returns a Reference to that object, so that it can be assigned to a variable. The assignment then gives dog the value of a Reference to your newly created Object.

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

#5


3  

new Dog() will instantiate an object Dog ie) it will create a memory for the object. You need to access the variable to manipulate some operations. For that you need an reference that is Dog myDog. If you try to print the object it will print an non readable value which is nothing but the address.

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

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