在Java中将String转换为Long (对象)的最首选方法是什么。
Long a = new Long(str);或
Long a = Long.parseLong(str);这里是否有一种正确的方法,因为两者似乎具有相同的可读性,并且在第一个方法中增加一个额外的autoboxing步骤是否可以接受?
发布于 2016-09-29 15:01:06
仔细查看返回类型:
Long.parseLong(String)返回一个原语 long,因此在本例中将重新装箱:Long a = Long.parseLong(str);。new Long(String)将在每种情况下创建一个新的 Long对象。所以,不要这样做,但去做3)Long.valueOf(String)返回一个Long对象,并将返回某些值的缓存实例--因此,如果您需要一个Long,这是首选变量。在检查java.lang.Long源代码时,缓存包含以下值(SunJDK1.8):
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}发布于 2016-09-29 15:01:26
最好的方法是Long.valueOf(str),因为它依赖于Long.valueOf(long),它使用内部缓存,从而提高了效率,因为如果需要,它将重用Long从-128到127的缓存实例。
返回表示指定长值的
Long实例。如果不需要一个新的长实例,则通常应该优先使用此方法而不是构造函数Long(long),因为该方法可能会通过缓存频繁请求的值来获得更好的空间和时间性能。注意,与Integer类中的对应方法不同,在特定范围内缓存值不需要此方法。
一般来说,使用包装类的static工厂方法valueOf(str)是一个很好的实践,比如Integer、Boolean、Long、.由于大多数实例在可能的时候重用实例,因此相对于相应的parse方法或构造函数,它们在内存占用方面可能更高效。
有效Java Item 1摘录,作者:乔舒亚·布洛赫
您通常可以避免使用静态工厂方法(项目1)来创建不必要的对象,而不是在提供两者的不可变类上使用构造函数。例如,静态工厂方法
Boolean.valueOf(String)几乎总是比构造函数Boolean(String)更可取。构造函数每次调用时都会创建一个新对象,而静态工厂方法从来不需要这样做,在实践中也不会这样做。
发布于 2016-09-29 17:04:38
我建议在所有其他选项中使用Long.parseLong,因为:
Long.valueOf,Long(string)都依赖于Long.parseLong方法,该方法作为每个String到Long转换的核心方法。Long.parseLong,或者在对象为String类型时通过Long.valueOf调用。(显然,使用直接调用)。官方文件和源代码链接 (为什么不使用Byte而不是Long,因为缓存也不会保存所有长值,即使这个范围也适用于整数)。来自官方文档
public static Long valueOf(String s)
throws NumberFormatException
Returns a Long object holding the value of the specified String. The argument is interpreted as representing a signed decimal long, exactly as if the argument were given to the parseLong(java.lang.String) method. The result is a Long object that represents the integer value specified by the string.
**In other words, this method returns a Long object equal to the value of:**
new Long(Long.parseLong(s))
// internally calls to Long.valueOf when you pass string
public static Long valueOf(String s) throws NumberFormatException
{
return Long.valueOf(parseLong(s, 10));
}new Long对象的直接包装对象Long.valueOf 返回是一条假语句,因为根据Long.parseLong的内部用法(返回原语long),Long.parseLong的原始输出将通过创建Long类的新对象来转换为Wrapper对象,因此您希望使用直接Boxing或调用Long.valueOf=>Long.parseLong=>new Long--关于缓存的更多信息(如果传递值较长):
当您希望使用==进行对象类型的等式检查(如实习生字符串)时,缓存几乎没有什么帮助。Long cache只保留一个包含在-128 to 127范围内的对象的静态数组,因此如果数字超出此范围,则无法使用==运算符进行等式检查(您不相信,请尝试下面的示例)
示例:
Long b2=128L;
Long b3=128L;
Long aa=Long.valueOf("134");
Long ab=Long.valueOf("134");
System.out.println(b2==b3); // no cache for out of range values
System.out.println(aa==ab); // no cache for out of range values
System.out.println(aa.equals(ab)); // must use equals for equality check
System.out.println(b2.equals(b3));
b2=44; // between -128 to 127 it will work
b3=44;
System.out.println(b2==b3);输出:
false
false
true
true
true因此,尝试使用equals进行等式检查。
为什么缓存需要:因为-128到127包含的数字需要给出身份,这是因为JLS (5.1.7)的性能原因,所以在这种情况下,缓存并不是为了提高时间/空间效率。
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache , range is clearly seen
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}结论:
Long.parseLong。Wrapper类一起使用数字时,Wrapper机制的缓存才能工作。https://stackoverflow.com/questions/39773695
复制相似问题