Java中有多less个string对象?
我的朋友给我一个问题,他在一个模拟考试中看到关于string对象的Javaauthentication:
String makeStrings(){ String s = "HI"; s = s + "5"; s = s.substring(0,1); s = s.toLowerCase(); return s.toString(); }
调用此方法时将创build多less个string对象? 考试给出的正确答案是3,但是我认为是5。
- “HI”
- “5”
- “HI5”
- “H”
- “H”
我错了吗?
String makeStrings() { String s = "HI"; //String literal s = s + "5"; //concatenation creates new String object (1) s = s.substring(0,1); //creates new String object (2) s = s.toLowerCase(); //creates new String object (3) return s.toString(); //returns already defined String }
关于连接,当创build一个新的String时, JVM
使用StringBuilder
,即:
s = new StringBuilder(s).append("5").toString();
toString()
为一个StringBuilder
是:
public String toString() { return new String(value, 0, count); //so a new String is created }
substring
创build一个新的String对象, 除非整个String
被索引:
public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > count) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex) } return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); }
toString()
不会创build一个新的String:
public String toString() { return this; }
toLowerCase()
是一个相当长的方法,但足以说,如果String
不是全部小写,它将返回一个new String
。
鉴于提供的答案是3
,正如Jon Skeet所build议的那样,我们可以假定两个string字面值已经在string池中。 有关何时将string添加到池中的更多信息,请参阅有关Javastring池的问题 。
s = s + "5";
被翻译成:
String s = new StringBuilder(s).append("5").toString();
现在,创build一个对象。
s = s.substring(0,1);
创build一个新的string。
s = s.toLowerCase();
创build一个新的对象。
return s.toString();
不会创build一个string,它会返回一个已经创build的string。
其他一些答案是有道理的,但是string呢?
String s = "HI";
对于string文字,当一个.java文件被编译成一个.class文件时,任何string都以特殊的方式logging下来,就像所有的常量一样。 当一个类被加载时(注意加载发生在初始化之前),JVM通过类的代码并查找string文字。
当它find一个时,它会检查是否已经从堆中引用了等价的string。 如果不是,则在堆上创build一个String实例,并将该对象的引用存储在常量表中
一旦对该string对象进行了引用,则在整个程序中对该string文本的任何引用都将简单地replace为对string文字池引用的对象的引用。
因此,应该有四个Java对象,尽pipe当同一个方法被一次又一次地调用,那么只有三个对象,如应用程序中string文字池包含文字“HI”。
另外,关于为什么在执行上述方法块时创build新对象的更多信息,我们还可以检查不同string的哈希码( String
是不可变的)。
public static void main(String[] args) { NumberOfString str = new NumberOfString(); String s = str.makeStrings(); System.out.println(s.hashCode()); } public String makeStrings() { String s = "HI"; System.out.println(s.hashCode()); s = s + "5"; System.out.println(s.hashCode()); s = s.substring(0, 1); System.out.println(s.hashCode()); s = s.toLowerCase(); System.out.println(s.hashCode()); return s.toString(); }
你得到以下输出:
2305 71508 72 104 104
我们不应该在上面的例子中的string字面值对吗?
- 在日志大小和时间上滚动回滚日志
- 什么是StackOverflowError?
- 评估列表是否为空JSTL
- Javabean和EJB之间的区别
- Eclipse返回错误消息“Java已启动,但返回退出代码= 1”
- java.lang.ClassNotFoundException:启动Simple Struts2应用程序时,org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- 里面的OnClickListener我不能访问很多东西 – 如何处理?
- NoClassDefFoundError:org / slf4j / impl / StaticLoggerBinder
- System.currentTimeMillis()返回UTC时间?