2013-03-15 114 views
-2

我对使用java或C++的对象的管理有疑问。对象的管理

的情况是,在C++中,当你想创建一个动态的对象,一个是生存比上创建它的块范围更多,你必须做一个新的,您将收到一个指针。否则,如果你只是想在块范围内使用这个对象,你不需要使用新的创建它...

但是在Java中,你总是必须使用new创建它们,因为如果不是,对象为null,您可以使用它。

这是为什么?它是如何工作的?

谢谢

+1

为什么?因为Java和C++是具有完全不同对象模型和不同规则的两种不同语言。 (他们都碰巧有一个关键字'新',具有不同的含义。) – aschepler 2013-03-15 14:44:38

回答

2

我能想到的最好的比喻,是在C各类++的行为有些象Java原语。如果您在Java中声明了一个原语,则不必使用new,您可以立即使用该变量。但是像C++中的大多数对象一样,这样的基元只能在当前范围内生存。在C++中,如果你想让一个对象存在于当前作用域之外,你需要告诉编译器,因为它必须在堆上分配内存而不是堆栈。您可以使用new来完成此操作。在Java中,所有对象(保存原语)都分配在堆上,堆栈中唯一的数据是对堆内存和原语的引用。因此,在Java中,所有内存分配均使用new完成。

以上是对Java中实际内存管理的简化。有关基元的堆栈/堆内存更深入的讨论,请看看here

+1

这里有一个很好的堆栈/堆栈/基元与对象的解释;以上是一些简化。 http://stackoverflow.com/questions/3646632/does-the-java-primitives-go-on-the-stack-or-the-heap – James 2013-03-15 14:57:30

+0

那么,这就是我暗示的“*有点*”。 ;)但是感谢链接,我将它包含在答案中。 – JSQuareD 2013-03-15 15:01:19

+0

嘿,只是帮助... – James 2013-03-15 15:08:55

0

基本上,这就是它的工作原理。一旦使用了新的关键字,那么对象就会被创建并弹出到堆上。如果你没有在方法外引用这个对象,那么垃圾回收器会自动回收它。 我建议你阅读一下Java堆和垃圾回收的基础知识,以获得更好的理解。那里有很多资源。我总是为新来的人推荐头等书。

+0

问题是关于C++,在C++中没有垃圾收集器... – JSQuareD 2013-03-15 14:51:03

+0

我看到OP了解它如何在C++中工作,但不是什么“新”的点在Java中。 – James 2013-03-15 14:53:46

+0

啊,我只是反过来......重读他的文章,我不再肯定这种方式或其他... – JSQuareD 2013-03-15 14:56:12

1

这种差异是因为Java正在使用垃圾回收器进行内存管理。由于垃圾收集器在其作用域结束时(并且它没有可达引用)会自动释放对象,因此不需要有两种不同的方法来创建对象。

你可以说,在Java对象自动的行为类似于C++这是不初始化的对象,因为你不必去想删除它们。

0

在C++中,任何东西都可以在栈上分配(也就是当你说

ObjectType o; 
用C

++会发生什么。

在Java中,只有原语确实在栈中分配。对象是从来没有在栈上(这只是它是如何)。当你说

ObjectType o; 

在Java中,没有对象被分配,只有一个“变量”。变量可以有一个对象的引用,但在日现在它没有。从本质上讲,它是等于说

ObjectType *o = NULL 
用C++

为了实际分配一个对象本参考引用,你必须在Java中使用new

0

在C++中,当你想要创建一个动态对象时,你必须创建一个新的对象,它必须在创建它的地方创建一个新的块,然后你会收到一个指针。

操作者在C++分配在堆空间。堆是主存的大部分。如果你这样做,你有责任在使用免费操作员完成该空间时释放该空间。

否则,如果你只是想在块范围内使用这个对象,你不需要它使用新的创造......

当你在C++中声明变量,内存分配在堆栈。堆栈是,当地的数据存储和一切你上推(添加)在执行功能会自动弹出(删除)函数返回时。堆栈通常比堆小很多,但使用它有很多优点:您不需要担心内存管理,速度更快等。

但是在Java中,您总是必须使用new创建它们,因为如果不是,则该对象为null,您可以使用它。

当你在声明Java变量,它们再次存储在堆栈上 你知道,你不上的原始数据类型调用(例如int i = new int(3);)。当你这样做你Object x;声明x将是一个参考Object类型的对象。但是,你不要一个值分配给它,这样的引用是(不是对象,因为没有一个)。粗略地说,在Java中,运算符在堆上分配空间,调用它所调用的对象的构造函数,并返回对构造对象的引用。与C++的区别在于你不需要自己释放对象 - 有一个垃圾回收器。本质上,它所做的是监视有多少引用指向一个对象,如果它们归零,则会自动删除该对象。

所以,当你做

Object y = new Object(); 
x = y;
你会得到两个引用(x和y)指向同一个对象。当你在 bar()...部分函数调用这样
Object foo() { 
    Object y = new Object(); 
    return y; 
}

void bar() { Object x = foo(); ... }

你将有参考 x,指着 foo()创建的对象。由于 foo已返回,因此 y引用已被释放,因此在该程序的 ...部分中只能引用该对象。如果您不复制参考 barbar返回的任何位置,则会有0个对该对象的引用,并且垃圾收集器将 收集它(尽管不是立即)。

-Stan