我是一名转向Java的C ++开发人员。两种语言之间存在相似之处,我对java中的堆使用有一些疑问。
如果我不需要在C ++中将变量保留在函数范围之外,我只需将它分配到堆栈中,然后让调用栈负责清理它。 因此,这段代码在C ++中完全合法,
std::unordered_map<std::string, int> map;
在Java中,如果我写一个类似的代码,
HashMap<String, Integer> map;
编译器给我一个警告,表示map的值未初始化。要取消警告,我必须使用,
HashMap<String, Integer> map = new HashMap<>();
我的问题是,即使我不需要将它持久化到调用堆栈之外,它是一个Java会议来创建每个对象吗?
答案 0 :(得分:6)
Java根本没有使用C ++样式代码分配map
并且警告你。你应该program to the interface Map
。你可以用
Map<String, Integer> map = null;
或者,如示例,
Map<String, Integer> map = new HashMap<>();
答案 1 :(得分:5)
class Mutex {
private:
int e;
pthread_mutex_t mutex_;
public:
Mutex(): e(0) {
e = pthread_mutex_init(&mutex_);
}
void lock() {
e = pthread_mutex_lock(&mutex_);
if( e == EINVAL )
{
throw MutexInitException();
}
else (e ) {
throw MutexLockException();
}
}
// ... the rest of your class
};
只声明一个变量,而不是初始化它(也没有分配内存)。如果您在为其分配内容之前尝试使用它,则会出错。
Map<String, Integer> map;
创建一个HashMap对象,允许您调用所有HashMap方法并访问数据。
HashMap<String, Integer> map = new HashMap<>();
创建一个Map对象,概括HashMap。您无法访问某些特定于HashMap的方法(you can check the docs),但如果您不需要它们,那么这种方式会更好(通常更通用,更好,如其他答案中所述) )。
Map<String, Integer> map = new HashMap<>();
为地图变量指定null。它会关闭编译器,但是如果你在调用构造函数之前尝试对它做任何事情,那么你将获得Map<String, Integer> map = null;
并且程序将崩溃。
答案 2 :(得分:3)
在Java中,您处理对象的引用,因此您需要使用new或以某种方式分配给另一个现有对象,或者变量将是null
,就像C ++中的未初始化指针一样。
变量将在块的末尾超出范围,就像在C ++中一样,并且有资格进行垃圾回收。也就是说,除非某些其他代码保留对它的引用,例如通过从函数返回它或将其放在列表或映射中。
答案 3 :(得分:3)
要拥抱Java,你会放弃一些(很多?)对内存的控制 管理与C ++相比。好消息是你(最终)不会错过它。
最初以“简单”的方式编写代码,然后对其进行分析 如果发现瓶颈,请采取行动并采取对策。 遵循口头禅:让它运行,使其正确,使其快速。
我预测你会发现FEW有机会改善表现 已经有像jdbc连接这样的池框架的东西,但不是 接受我的话 - 自己验证。 : - )
fwiw,使用热点编译器和当代JVM垃圾收集 一切都表现得很好。 白银:从C ++进入Java,你将比许多Java程序员更深入地了解内存管理,如果你想在JVM之外集成到JNI之类的东西(https://en.wikipedia.org/wiki/Java_Native_Interface )为了好玩,您可能会喜欢阅读Java Performance Tuning Newsletter:http://www.javaperformancetuning.com/news/news179.shtml
答案 4 :(得分:2)
在Java中,(几乎)每个对象都在“堆”上,如果范围中没有引用该对象的变量,则在垃圾收集器运行时会自动从堆中删除对象。
与C ++类似,对象的变量在实例化之前没有值。因此,为什么您的编译器会警告您Map<String, Integer> map;
未初始化。不过,这只是一个警告。编译器警告你,这可能是你错过的错误。要超越这个,您需要为变量赋值。这可以通过初始化对象(说:... = new HashMap<>();
)或手动为未初始化对象(null
指定默认值,表示:null
)来完成。