为什么引用数据类型指向?
Why do reference data types point?
考虑:
我了解对于原始数据类型,分配的内存(橙色矩形)包含您想要的内容,但对于引用数据类型,分配的内存包含您想要的内容 reference/pointer。
为什么要这样设计?对于通常是引用数据类型(对象、数组等)的东西,为什么不把你想要的东西放在橙色矩形中呢?
如果我们直接将对象存储在内存盒中,那么就不可能有多个引用指向同一个对象。如果我想做一些事情,比如将它作为参数传递给方法,这是有问题的。这会创建一个对该对象的新引用,并将其传入,从而允许该方法对其进行操作。如果该对象实际上在内存盒中,则它必须传入一个副本,这 a) 会消耗比需要更多的内存 space,并且 b) 意味着在函数中所做的更改不会影响原始文件对象,只是副本。
例如,如果对象实际上在内存框中,而不是在引用中,则以下代码将不起作用。
public class blah{
private ArrayList<String> array = new ArrayList<String>();
// if the object resided directly in memory, this method would do nothing of use
// as it would only make changes to the copy it was passed, rather than the original.
public void add Value(ArrayList<String> array, String value){
array.add(value);
}
}
那个橙色矩形有多大?
对于图元,您已经知道大小了。但是对于对象呢?对于具体的最终 类,您会知道已经使用了多少内存...但是其他情况呢?
例如:
InputStream x = new FileInputStream("foo");
如果变量 x
必须包含 所有 对象的字段(并且知道它是什么类型),那么它必须足够大FileInputStream
个字段。好的,在这种情况下我们可以解决这个问题,尽管 InputStream
变量的大小由其用法定义有点奇怪。这个怎么样:
InputStream x = getInputStream("foo");
编译器无法知道 getInputStream
将返回什么类型的对象 - 那么它如何知道 x
将有多大?当 x
的值是一个引用时,它就简单多了——无论它引用的对象的实际类型如何,它都是相同的大小。
当然,您希望能够在该对象的多个 "users" 之间共享对象,这就是使用引用变得非常高效的地方。 (我们不必每次传递值时都复制所有字段——我们只需复制引用。)将对象视为值而不是引用会大大改变语义。例如:
// A simple mutable type with get/setValue doing the obvious thing
MutableType x = new MutableType();
x.setValue(5);
MutableType y = x;
x.setValue(10);
System.out.println(y.getValue());
对于引用,这将打印 10,因为 x
和 y
只是对同一对象的引用。使用值类型语义,大概它会打印 5 。并非不合理 - 但语言的工作方式发生了很大变化。
然后还有其他的问题,不过我觉得可以入手:)
当然,C++ 可以解决所有这些问题,但是 Java 的设计者认为对所有非基本类型使用引用更简单。
考虑:
我了解对于原始数据类型,分配的内存(橙色矩形)包含您想要的内容,但对于引用数据类型,分配的内存包含您想要的内容 reference/pointer。
为什么要这样设计?对于通常是引用数据类型(对象、数组等)的东西,为什么不把你想要的东西放在橙色矩形中呢?
如果我们直接将对象存储在内存盒中,那么就不可能有多个引用指向同一个对象。如果我想做一些事情,比如将它作为参数传递给方法,这是有问题的。这会创建一个对该对象的新引用,并将其传入,从而允许该方法对其进行操作。如果该对象实际上在内存盒中,则它必须传入一个副本,这 a) 会消耗比需要更多的内存 space,并且 b) 意味着在函数中所做的更改不会影响原始文件对象,只是副本。
例如,如果对象实际上在内存框中,而不是在引用中,则以下代码将不起作用。
public class blah{
private ArrayList<String> array = new ArrayList<String>();
// if the object resided directly in memory, this method would do nothing of use
// as it would only make changes to the copy it was passed, rather than the original.
public void add Value(ArrayList<String> array, String value){
array.add(value);
}
}
那个橙色矩形有多大?
对于图元,您已经知道大小了。但是对于对象呢?对于具体的最终 类,您会知道已经使用了多少内存...但是其他情况呢?
例如:
InputStream x = new FileInputStream("foo");
如果变量 x
必须包含 所有 对象的字段(并且知道它是什么类型),那么它必须足够大FileInputStream
个字段。好的,在这种情况下我们可以解决这个问题,尽管 InputStream
变量的大小由其用法定义有点奇怪。这个怎么样:
InputStream x = getInputStream("foo");
编译器无法知道 getInputStream
将返回什么类型的对象 - 那么它如何知道 x
将有多大?当 x
的值是一个引用时,它就简单多了——无论它引用的对象的实际类型如何,它都是相同的大小。
当然,您希望能够在该对象的多个 "users" 之间共享对象,这就是使用引用变得非常高效的地方。 (我们不必每次传递值时都复制所有字段——我们只需复制引用。)将对象视为值而不是引用会大大改变语义。例如:
// A simple mutable type with get/setValue doing the obvious thing
MutableType x = new MutableType();
x.setValue(5);
MutableType y = x;
x.setValue(10);
System.out.println(y.getValue());
对于引用,这将打印 10,因为 x
和 y
只是对同一对象的引用。使用值类型语义,大概它会打印 5 。并非不合理 - 但语言的工作方式发生了很大变化。
然后还有其他的问题,不过我觉得可以入手:)
当然,C++ 可以解决所有这些问题,但是 Java 的设计者认为对所有非基本类型使用引用更简单。