我是 Java 新手,我对使用构造函数有一些疑问:
Map<String, Object> map = new HashMap<String, Object>();
map.put("one", new String("Hello"));//1
map.put("two", "world");//2
哪种说法更可怕?有什么区别?哪一个是最好的?
两种形式的作用相同,但在底层存在差异。如果您使用String
构造函数,您将跳过内部字符串池,始终创建一个新对象 - 而使用字符串文字首先在池中查找字符串,如果在那里找到它,它会被重用(仅创建一个新字符串,如果它之前不在池中) - 因此它更有效,因为它避免了不必要的对象实例化。顺便说一句,字符串可以从池中共享,因为它们是不可变的。
许多静态代码分析工具将String
构造函数的使用标记为违反良好的编程习惯,通常应该避免。
第一:
map.put("one", new String("Hello"));//1
几乎从不需要。这会创建一个不必要的String
对象。尽管在运行时并不重要,因为它只是一个对象。但是当在某个循环中这样使用时,肯定会有所作为。循环中的对象创建是昂贵的操作。
另一方面,第二个:
map.put("two", "world");//2
将重新使用来自String Literal Pool的 interned string literal 。字符串字面量池是对在堆上创建的字符串对象的引用的集合。Java 自动实习字符串文字,因此多次使用相同的字符串文字不会每次都创建一个新的字符串对象。当第一次遇到字符串文字时,会在堆上为其创建一个对象,并且对该对象的引用存储在字符串文字池中。
在随后使用相同的字符串文字时,将使用来自文字池的相同字符串引用,而不是在堆上创建新的字符串对象。这是安全的,因为字符串是不可变的,我们可以共享对同一个字符串对象的引用。所以,当然这是更好的方法。
你应该做
map.put("two", "world");
因为#2方法每次都会创建新字符串,而无需像Oscar提到的那样在池中寻找已经存在的字符串。