考虑一下:
据我所知,对于原始数据类型,分配的内存(橙色矩形)包含您想要的内容,但对于引用数据类型,分配的内存包含指向您想要的内容的引用/指针。
为什么要这样设计呢?对于通常是参考数据类型(对象,数组等)的东西,为什么不把你想要的东西放在橙色矩形中呢?
答案 0 :(得分:5)
橙色矩形有多大?
对于基元,您已经知道了尺寸。但对象呢?对于具体的最终课程,您已经知道将要使用多少内存......但是其他情况呢?
例如:
InputStream x = new FileInputStream("foo");
如果变量x
必须包含 all 对象的字段(并知道它是什么类型),那么它必须足够大,以便所有{ {1}}字段。好的,在这种情况下我们可以管理它,虽然它的用法定义FileInputStream
变量的大小有点奇怪。那怎么样:
InputStream
编译器无法知道InputStream x = getInputStream("foo");
将返回什么类型的对象 - 那么它怎么知道getInputStream
会有多大?当x
的值是引用时,它更简单 - 它的大小相同,无论它引用的对象的实际类型如何。
当然,您希望能够在各种用户之间共享对象"该对象,使用引用变得非常有效。 (我们不必在每次传递值时都复制所有字段 - 我们只需复制引用。)将对象作为值而不是引用来处理会更改语义。例如:
x
通过引用,这会打印10,因为// 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());
和x
只是对同一对象的引用。使用值类型语义,可能会打印5。这不是不合理的 - 但语言的工作方式发生了很大的变化。
此外还有其他问题,但我认为这足以开始:)
当然,C ++可以解决所有这些问题,但Java的设计者认为只使用所有非原始类型的引用更简单。
答案 1 :(得分:3)
如果我们将对象直接存储在内存盒中,则不可能有多个引用指向同一个对象。如果我想做一些事情,比如将它作为参数传递给方法,这就有问题了。这将创建对该对象的新引用,并将其传入,允许该方法对其进行操作。如果对象实际上在内存盒中,则必须传入一个副本,其中a)将占用比所需更多的内存空间,并且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);
}
}