Java中的变量分配

时间:2015-12-26 22:56:38

标签: java c++

我是一名转向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会议来创建每个对象吗?

5 个答案:

答案 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)来完成。