Java中的变量分配

Variable allocation in Java

本文关键字:分配 变量 Java      更新时间:2023-10-16

我是一名进入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惯例吗?

Java根本没有用C++风格的代码分配map,并且警告您。您应该编程到接口Map。你可以用之类的东西来克服这个警告

Map<String, Integer> map = null;

或者,如示例中所示,

Map<String, Integer> map = new HashMap<>();
Map<String, Integer> map;

只声明一个变量,而不初始化它(也不分配内存)。如果你在给它分配东西之前试图使用它,它会给出一个错误。

HashMap<String, Integer> map = new HashMap<>();

创建一个HashMap对象,允许您调用所有HashMap方法并访问数据。

Map<String, Integer> map = new HashMap<>();

创建一个Map对象,对HashMap进行泛化。您无法访问某些特定于HashMap的方法(您可以查看文档),但如果您不需要它们,最好采用这种方式(通常越通用越好,如其他答案中所述)。

Map<String, Integer> map = null;

为映射变量指定null。它会关闭编译器,但如果在调用构造函数之前尝试对其执行任何操作,则会得到NullPointerException,并且程序将崩溃。

在Java中,您处理对对象的引用,因此您需要使用new或以某种方式分配给另一个现有对象,否则变量将是null,就像C++中未初始化的指针一样。

该变量将在块末尾超出作用域,就像C++中一样,并符合垃圾回收的条件。也就是说,除非其他代码包含对它的引用,例如从函数返回它或将它放在列表或映射中。

要接受Java,您将放弃对内存的一些(很多?)控制管理与C++相比。好消息是你(最终)不会错过的。

最初以"简单"的方式编写代码,然后为性能,并在发现瓶颈时采取对策。遵循咒语:让它跑起来,让它正确,让它快起来。

我预测,除了已经有像jdbc连接这样的池化框架,但没有相信我的话-自己核实。:-)

fwiw,带有热点编译器和当代JVM垃圾收集一切都表现得很好。

一线希望:从C++进入Java,您将比许多Java程序员对内存管理有更深入的理解,如果您想在JVM之外集成到JNI(https://en.wikipedia.org/wiki/Java_Native_Interface)

只是为了好玩,您可能喜欢阅读Java性能调整时事通讯:http://www.javaperformancetuning.com/news/news179.shtml

在Java中,(几乎)每个对象都在"堆"上,如果作用域中没有任何引用该对象的变量,则在垃圾收集器运行时,对象会自动从堆中删除。

与C++类似,对象的变量在实例化之前没有值。因此,编译器会警告您Map<String, Integer> map;未初始化。不过,这只是一个警告。编译器警告您,这可能是您遗漏的一个错误。为了克服这一点,您需要为变量分配一些值。这可以通过初始化对象(称为:... = new HashMap<>();)或手动为其指定未初始化对象的默认值(null,称为:null)来完成。